參考
裝飾模式優(yōu)缺點(diǎn)
裝飾模式游戲例子
設(shè)計(jì)模式(九)裝飾模式(Decorator)
假如有個(gè)食物類茄唐,不同的做法蒸炒煎炸要生成不同的基類。就是四個(gè)子類:蒸食物惠昔、炒食物洒沦,煎食物,炸食物价淌。如果還要有兩種做法的子類呢申眼,還要寫蒸炒食物,蒸煎食物……三種做法的更夸張蝉衣,子類多到爆炸括尸。并且為了應(yīng)對(duì)不同情況,要把所有可能用到的子類都提前寫出來(lái)病毡,而不是到使用時(shí)再隨時(shí)寫濒翻。
處理辦法:
食物類增加四個(gè)屬性來(lái)標(biāo)記做法:是否蒸,是否炒啦膜,是否煎有送,是否炸……
那要是有蒸兩遍的呢?看來(lái)這個(gè)屬性不能用bool類型僧家,還要用int類型雀摘。
當(dāng)然這樣做,對(duì)應(yīng)不同的做法組合八拱,處理方法里要寫很多if判斷上述的四個(gè)屬性組合阵赠,去做對(duì)應(yīng)的邏輯。食物類也因此變得龐大肌稻,邏輯超多清蚀。如果需要40個(gè)屬性,甚至400個(gè)屬性呢……這種直接在基類中處理所有邏輯也違反了開放封閉原則爹谭,即基類是可擴(kuò)展的枷邪,但不能修改∨捣玻可以預(yù)見到齿风,隨著食物的做法增多,必然要不停地修改基類绑洛,以及基類的if判斷救斑。
有沒有辦法做到,生成一個(gè)食物的子類真屯,即滿足子類要求脸候,又可以處理不同的做法呢。答案就是組合,即設(shè)計(jì)模式中的裝飾模式运沦。
- abstract class Food食物類
function todo()
- Chicken extends Food雞肉類
- Duck extends Food鴨肉類
- FoodDecoration extends Food
- SteameFood extends FoodDecoration//子類蒸食物泵额,仍然是Food的子類
private Food food;//使用構(gòu)造方法傳入的變量進(jìn)行組合
public SteameFood(Food f){
this.food = f;
}
override function todo(){
//food.todo()
//蒸
} - RoastFood extends FoodDecoration//子類烤食物,仍然是Food的子類
private Food food;//使用構(gòu)造方法傳入的變量進(jìn)行組合
public RoastFood(Food f){
this.food = f;
}
override function todo(){
//food.todo()
//烤
}
運(yùn)行時(shí)就可以自由組合了:
// 測(cè)試單純的食物
Food f1 = new Chicken();
System.out.println(f1.getDesc());
System.out.println("----------------------");
// 測(cè)試單重修飾的食物
RoastFood rf = new RoastFood(f1);
System.out.println(rf.getDesc());
System.out.println("----------------------");
// 測(cè)試多重修飾的食物
SteamedFood sf = new SteamedFood(rf);
System.out.println(sf.getDesc());
執(zhí)行結(jié)果:
雞肉
----------------------
烤雞肉
----------------------
蒸烤雞肉
可以看出携添,N種做法只要N個(gè)子類嫁盲。使用的時(shí)候多重裝飾即可,自己安排好裝飾順序烈掠。