責任鏈模式也是我們比較常用的一種模式,我在《Groovy探索之責任鏈模式》中有個探索。大家也可以在網上搜索,應該有很多這方面的文章。
在這裡,我們將使用自定義的Range類來實現責任鏈模式,使用的例子還是在《Groovy探索之責任鏈模式》一文中所談到的"孫悟空大戰二郎神"的這個情節。這樣,我們可以把這兩篇的文字結合起來看,使得我們能夠對比這兩種開發方式。使得我們能夠深入的理解自定義Range類的使用。
在"孫悟空大戰二郎神"這個情節裡,重點講述的是兩人的變幻大戰:其中,孫悟空分別變幻成"麻雀"、"大鹚鳥"和"雨",企圖躲過二郎神的追殺;而二郎神則分別變成"鷹"、"大海鶴"和"魚鷹"來吃掉孫悟空的相應的變幻。原文情節可以在《Groovy探索之責任鏈模式》看到。
這個情節使用責任鏈模式來實現是易於理解的,但是使用自定義的Range類來實現,則更有Groovy語言的編程風格。
現在,我們來看看使用自定義的Range類來實現的具體代碼。
首先,我們要實現的還是自定義的Range類:
package range.chain;
class Base implements Comparable{
static protected types = ['cormorant','sparrow','fish']
protected int index = 0
protected type
protected getIndex()
{
this.index = this.types.indexOf(type)
}
def next()
{
Factory.getObject(types[(index+1)%types.size()])
}
def previous()
{
Factory.getObject(types[index-1])
}
int compareTo(Object other)
{
index<=>other.index
}
}
這個Base類和《Groovy探索 自定義Range 二 自定義Range類與Decorate模式》中實現的Base類沒有什麼區別,除了index屬性的賦值不同以外。
這就提醒我們,是否可以做一個通用的自定義Range類?
接著是Factory類:
package range.chain;
class Factory {
static def getObject(type)
{
if(type == 'cormorant')
{
return new Crane()
}
else if(type == 'sparrow')
{
return new Hawk()
}
else if(type == 'fish')
{
return new Osprey()
}
}
}
這個Factory類跟前面所實現的Factory類就不一樣了,因為我們的type輸入的孫悟空的變幻,而各個責任模塊卻是二郎神的變幻,這就導致了我們的這個自定義Range在擴展上的困難。
然後,我們需要實現各個責任模塊了,當然了,這些類無一例外的都要繼承Base類了。我們先來看看Crane類:
package range.chain;
class Crane extends Base{
def Crane()
{
this.type = 'cormorant'
this.getIndex()
}
def fight()
{
println 'crane eat cormorant!'
}
}
這個類跟責任鏈模式所對應的Crane類比較起來,就更為簡單一些,這也是我們增加了一個自定義Base類後得到的一點點好處。同樣,我們來看看Hawk類:
package range.chain;
class Hawk extends Base{
def Hawk()
{
this.type = 'sparrow'
this.getIndex()
}
def fight()
{
println 'hawk eat sparrow!'
}
}
跟Crane類的實現一模一樣,最後是Osprey類的實現:
package range.chain;
class Osprey extends Base{
def Osprey()
{
this.type = 'fish'
this.getIndex()
}
def fight()
{
println 'osprey eat fish'
}
}
現在,我們就可以來測試這種實現方式了:
def crane = new Crane()
def osprey = new Osprey()
def wukong = 'fish'
(crane..osprey).find{
Base.types[it.index] == wukong
}.fight()
運行結果為:
osprey eat fish
到現在為止,我們已經完全的實現了"孫悟空大戰二郎神"的情節。比較使用責任鏈模式的實現和使用自定義Range類的實現,我們感覺使用自定義的Range類的實現在擴展性上要比使用責任鏈模式的實現要差。因為我們要擴展使用自定義的Range類的實現,我們不得不修改Factory類,而使用責任鏈模式的實現則不需要這樣做。
但是,在使用自定義的Range類的實現中,我們的各個責任模塊則更為簡單,不需要往下傳遞責任,這是自定義Range類的功能。
除此之外,如果各個責任模塊有多個方法。比如,我們的"Crane"類、"Hawk"類和"Osprey"類各自比上面的例子多了一個"descrition"方法。
則使用責任鏈模式的實現的客戶端為:
def wukong = 'fish'
def erlangshen = new Hawk(new Osprey(new Crane(new Other())))
erlangshen.fight(wukong)
erlangshen. descrition(wukong)
這裡的兩個方法的調用,則責任需要傳遞兩次,而自定義Range類的實現的客戶端為:
def crane = new Crane()
def osprey = new Osprey()
def wukong = 'fish'
def erlangshen = (crane..osprey).find{
Base.types[it.index] == wukong
}
erlangshen.fight()
erlangshen.description()
而用自定義Range類的實現則只需要傳遞一次,似乎在算法上更為有效率。