裝飾模式可以給我們很好的幫助,通過裝飾模式重新封裝一個類,而不是通過繼承來完成,
簡單點說,三個繼承關係 Father,Son,GrandSon 三個類,我要再 Son 類上增強一些功能怎麼辦?
我想你會堅決的頂回去!不允許,對了,爲什麼呢?你增強的功能是修改 Son 類中的方法嗎?增加方法嗎 ?
對 GrandSon 的影響哪?特別是 GrandSon 有多個的情況,你怎麼辦?這個評估的工作量就是夠你受的,所以這個是不允許的,那還是要解決問題的呀,怎麼辦?
通過建立 SonDecorator 類來修飾 Son,等於說是創建了一個新的類,這個對原有程序沒有變更,通過擴充很好的完成了這次變更。
以煮咖啡爲例:
public abstract class Cafe
{
public abstract void Cook(); //煮咖啡
}
//摩卡咖啡
public class MochaCafe extends Cafe
{
public void Cook() {
//煮摩卡咖啡
}
}
//貓屎咖啡
public class CivetCoffee extends Cafe
{
public void Cook() {
//煮貓屎咖啡
}
}
//帶牛奶的摩卡咖啡
public class MilkMochaCafe extends MochaCafe
{
public void AddMilk()
{
//加一些牛奶
}
public void Cook() {
//煮貓屎咖啡
super.Cook();
//煮完以後 再加牛奶
AddMilk();
}
}
//帶糖的貓屎咖啡
public class SugarCivetCoffee extends MochaCafe
{
public void AddSugar()
{
//加一些糖
}
public void Cook() {
//煮貓屎咖啡
super.Cook();
//煮完以後 再加一些糖
AddSugar();
}
}
咖啡的種類越來越多,配料的除了糖和牛奶 還 增加了蜂蜜等,繼承關係變得越來越多。
繼承關係越多系統架構越複雜,維護成本就會變高。
裝飾者,通過組合方式來擴展功能,而非繼承的方式。
我們來看下如何處理:
//摩卡咖啡裝飾者
public class CafeDecorator extends MochaCafe
{
private MochaCafe mochaCafe;
public CafeDecorator(MochaCafe mochaCafe) {
this.mochaCafe = mochaCafe;
}
public void AddSugar()
{
//加一些糖
}
public void AddMilk()
{
//加牛奶
}
public void Cook()
{
super.Cook();
AddSugar(); //煮咖啡之後加點糖
AddMilk(); //煮咖啡之後加牛奶
}
}