顧客可以需要任何種類的咖啡,我們可以根據Range的范圍來調節。你可能會說,且慢,如果我只需要咖啡加奶,怎麼辦?
這就要麻煩一點:
def c = new Coffee()
def m = new Milk()
m.types = ['Coffee','Milk']
(c..m).each{
println it.description()
}
麻煩在於我們不能使用"Base"類默認的"types"的值了,需要自定義"types"的值,如:
m.types = ['Coffe','Milk']
運行結果為:
Coffee
with milk
到了這裡,你可能還會說,且慢,Decorate模式擁有良好的擴展性,你使用自定義Range類實現的咖啡系列也有良好的擴展性嗎?
我們說,當然,自定義Range類實現的咖啡系列依然有著良好的擴展性。我們來看看實例吧。
比如,我們想在上面例子的基礎上增加一個咖啡類型:巧克力咖啡。我們就可以直接增加下面的類:
package range;
class Chocolate extends Base{
def Chocolate()
{
this.type = 'Chocolate'
this.getIndex()
}
def description()
{
'with chocolate'
}
def price()
{
8
}
}
這都很簡單,沒有什麼特別的。現在,我們就可以使用巧克力咖啡了:
def coffee = new Coffee()
def chocolate = new Chocolate()
chocolate.types = ['Coffee','Ice','Milk','Sugar','Chocolate']
(coffee..chocolate).each{
println it.description()
}
運行結果為:
Coffee
with ice
with milk
with sugar
with chocolate
到現在為止,Decorate模式所有的功能我們使用自定義Range類一一實現,我們可以這樣說,使用自定義的Range類能夠替代Decorate模式。
你可能會說,僅僅是替代而已,但使用自定義的Range類來實現該功能似乎比Decorate模式更為麻煩,至少要比Decorate模式多寫一個自定義的Range類,如上面的"Base"類。這樣的話,我在實際編碼的過程中,是不大會使用自定義的Range類的。
但實際情況是,使用自定義的Range類實現的咖啡系列比起使用Decorate模式實現的咖啡系列業務上更為靈活,因此比Decorate模式更為好用,特別是在業務比較復雜多變的情況下。
例如,我們需要實現某一個顧客他買了什麼樣的咖啡,以及他總的花費,就可以如下編碼:
def des1 = ''
def total = 0
(coffee..sugar).each{
des1 += it.description()+' '
total += it.price()
}
println "Your need: ${des1}"
println "Your charge: ${total}"
運行結果為:
Your need: Coffee with ice with milk with sugar
Your charge: 19
再如,我們需要知道某一個顧客他的花費的詳細清單以及總的花費,就可以這樣編碼了,如下:
def des2 = ''
def total2 = 0
(coffee..sugar).each{
des2 += it.description()+' : '+it.price()+'\n'
total2 += it.price()
}
println "Your charge \n${des2}"
println "Your total charge: ${total2}"
運行結果為:
Your charge
Coffee : 10
with ice : 1
with milk : 5
with sugar : 3
Your total charge: 19
到現在為止,我們總共為咖啡系列寫了三個邏輯:首先是需要知道顧客買了什麼樣的咖啡,以便工作人員好加以配置;然後,我們的收銀人員需要知道顧客總共的花費;最後,我們的顧客則需要知道他的各個細項的開銷以及總的花費。
這些邏輯如果是使用Decorate模式來實現的話,我們需要為每一個咖啡系列的類實現三個獨立的方法來完成。
但是,如果我們使用自定義的Range類來實現的話,我們只需要為每一個咖啡系列的類實現兩個基本的方法即可。
想想看,如果業務邏輯更為復雜,那又會怎麼樣呢?
現在,使用自定義的Range類來實現的咖啡系列是不是已經讓我們更為激動了。最後,我們來做一個小結吧!
使用Decorate模式實現的咖啡系列似乎更為怪異,它需要把很多客戶端要使用到的邏輯集成到各個咖啡系列的類中去,這不符合面向對象設計的基本原則--類的功能要單一。我們的咖啡系列的類其實只有兩個簡單的功能:即各自的描述和價格。
使用Decorate模式實現的咖啡系列正因為把很多客戶端要使用到的邏輯集成到了各個類中去,使得我們的咖啡系列就難以擴展。比如,我們的客戶端需要增加功能,我們就不得不辛辛苦苦的到咖啡系列的各個類中去增加各自的方法。這種擴展性其實已經是一個很大的局限性了。
而使用自定義Range類實現的咖啡系列則把這種復雜的業務交給了客戶端自己處理,我們咖啡系列的各個類只需要實現最基本的功能,即:各自的描述和價格。這樣,我們的咖啡系列就更加容易擴展了。