裝飾模式

裝飾模式可以給我們很好的幫助,通過裝飾模式重新封裝一個類,而不是通過繼承來完成,
簡單點說,三個繼承關係 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(); //煮咖啡之後加牛奶
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章