裝飾者模式可以動態(tài)地給一個對象添加一些額外的職責(zé)。就增加功能來說,Decorator模式相比生成子類更為靈活。

該模式的適用環(huán)境為:

(1)在不影響其他對象的情況下,以動態(tài)、透明的方式給單個對象添加職責(zé)。

(2)處理那些可以撤消的職責(zé)。

(3)當(dāng)不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用于生成子類。

實現(xiàn)該模式的關(guān)鍵步驟:

(1)Component(被裝飾對象基類):定義對象的接口,可以給這些對象動態(tài)增加職責(zé);

(2)ConcreteComponent(具體被裝飾對象):定義具體的對象,Decorator可以給它增加額外的職責(zé);

(3)Decorator(裝飾者抽象類):維護指向Component實例的引用,定義與Component一致的接口(也就是要繼承或?qū)崿F(xiàn)被裝飾對象基類);

(4)ConcreteDecorator(具體裝飾者):具體的裝飾對象,給內(nèi)部持有的具體被裝飾對象增加具體的職責(zé);

這樣講大家可能有些不好理解,那我們還是老規(guī)矩iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

入冬以后天氣越來越冷了,下班之后,做為資深吃貨,約上二三好友痛快的來場火鍋盛宴再爽不過了。說到火鍋,不得不提在成都吃過的大龍燚火鍋,各種鍋底,配菜應(yīng)有盡有,但我最喜歡的還是大龍燚火鍋原味鍋底、麻辣牛肉、大刀毛肚、天味香腸、砣砣牛肉、麻辣排骨等,想想都流口水啊。

說道這大家結(jié)合裝飾者的實現(xiàn)步驟,應(yīng)該有點感覺了吧,上文提到的鍋底,其實就是被裝飾對象的基類,配料其實就是裝飾者抽象類,大龍燚火鍋原味鍋底這些具體的鍋底也就是具體的被裝飾對象了,麻辣牛肉、大刀毛肚、天味香腸、砣砣牛肉、麻辣排骨這些裝飾鍋底用的各種配菜也就是具體的裝飾對象。說道這,大家應(yīng)該都豁然開朗了吧,下面我們開始具體的代碼實現(xiàn):

第一步:定義被裝飾對象基類(可以是抽象類也可以是接口)

1 public interface GuoDi { 2 public float cost();//鍋底當(dāng)然要有價錢啦 3 public String name();//名字也得有哦 4 }

第二步:定義具體被裝飾對象(也就是各種鍋底,這里定義兩種)

 

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)
 1 public class YuanYang implements GuoDi {  2  @Override  3 public float cost() {  4 return 48.0f;  5  }  6  @Override  7 public String name() {  8 return "鴛鴦鍋底";  9  } 10 } 11 public class DaLongYan implements GuoDi{ 12  @Override 13 public float cost() { 14 return 59.0f; 15  } 16  @Override 17 public String name() { 18 return "大龍燚火鍋原味鍋底"; 19  } 20 }
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

第三步:定義裝飾者抽象類

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)
 1 public abstract class PeiCai implements GuoDi {  2 private GuoDi guodi;  3 public FoodDecorator(GuoDi guodi) {  4 super();  5 this.guodi = guodi;  6  }  7  @Override  8 public float cost() {  9 return guodi.cost(); 10  } 11  @Override 12 public String name() { 13 return guodi.name(); 14  } 15 }
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

第四步:定義具體的裝飾者對象

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)
 1 public class MaLaNiuRou extends PeiCai {  2 public MaLaNiuRou(GuoDi guodi) {  3 super(guodi);  4  }  5  @Override  6 public float cost() {  7 return super.cost()+46f;  8  }  9  @Override 10 public String name() { 11 return super.name()+"+麻辣牛肉"; 12  } 13 } 14 public class MaoDu extends PeiCai { 15 16 public MaoDu(GuoDi guodi) { 17 super(guodi); 18  } 19  @Override 20 public float cost() { 21 return super.cost()+30f; 22  } 23  @Override 24 public String name() { 25 return super.name()+"+大刀毛肚"; 26  } 27 }
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

測試類:

 

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)
1 public class Test { 2 public static void main(String[] args) { 3 GuoDi  guodi = new DaLongYan ();//點個大龍燚火鍋原味鍋底 4 MaLaNiuRou y = new MaLaNiuRou(guodi);//來個麻辣牛肉 5 MaoDu  x = new MaoDu(y);//在麻辣牛肉的基礎(chǔ)上再來個大刀毛肚 6 System.out.println("一共點了"+x.name()+",共消費"+s.cost()); 7  } 8 }
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

輸出結(jié)果:

 1 一共點了大龍燚火鍋原味鍋底+麻辣牛肉+大刀毛肚,共消費135 

不知道大家這頓吃的滿意不,不行的話,咱去成都來頓真正的裝飾者設(shè)計模式,看我不把我的大龍燚火鍋原味鍋底裝飾的讓你走不動道iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)。