前言
裝飾模式,英文名稱:Decorator Pattern
。我第一次看到這個名稱想到的是另外一個詞語“裝修”,我就說說我對“裝修”的理解吧,大家一定要看清楚,是“裝修”,不是“裝飾”。在房子裝修的過程中,各種功能可以相互組合,來增加房子的功用。類似的,如果我們在軟件系統(tǒng)中,要給某個類型或者對象增加功能,如果使用“繼承”的方案來寫代碼,就會出現(xiàn)子類暴漲的情況。比如:IMarbleStyle是大理石風(fēng)格的一個功能,IKeepWarm是保溫的一個接口定義,IHouseSecurity是房子安全的一個接口,就三個接口來說,House是我們房子,我們的房子要什么功能就實現(xiàn)什么接口,如果房子要的是復(fù)合功能,接口不同的組合就有不同的結(jié)果,這樣就導(dǎo)致我們子類膨脹嚴(yán)重,如果需要在增加功能,子類會成指數(shù)增長。
裝飾模式的定義
上述的問題的根源在于我們“過度地使用了繼承來擴展對象的功能”,由于繼承為類型引入的靜態(tài)特質(zhì),所謂靜態(tài)特質(zhì),就是說如果想要某種功能,我們必須在編譯的時候就要定義這個類,這也是強類型語言的特點。靜態(tài),就是指在編譯的時候要確定的東西;動態(tài),是指運行時確定的東西。使得這種擴展方式缺乏靈活性;并且隨著子類的增多(擴展功能的增多),各種子類的組合(擴展功能的組合)會導(dǎo)致更多子類的膨脹(多繼承)。如何使“對象功能的擴展”能夠根據(jù)需要來動態(tài)(即運行時)地實現(xiàn)?同時避免“擴展功能的增多”帶來的子類膨脹問題?從而使得任何“功能擴展變化”所導(dǎo)致的影響降為最低?裝飾者模式解決此問題應(yīng)運而生,動態(tài)地給一個對象增加一些額外的職責(zé)。
裝飾模式的組成
-
抽象構(gòu)件角色(Component):給出一個抽象接口,以規(guī)范準(zhǔn)備接收附加責(zé)任的對象。
-
具體構(gòu)件角色(Concrete Component):定義一個將要接收附加責(zé)任的類。
-
裝飾角色(Decorator):持有一個構(gòu)件(Component)對象的實例,并實現(xiàn)一個與抽象構(gòu)件接口一致的接口。
-
具體裝飾角色(Concrete Decorator):負責(zé)給構(gòu)件對象添加上附加的責(zé)任。
裝飾模式的實現(xiàn)
以裝修房子為例,完成裝飾著模式的代碼實現(xiàn)
房子定義
/// <summary>
/// 該抽象類就是房子抽象接口的定義,該類型就相當(dāng)于是Component類型,是餃子餡,需要裝飾的,需要包裝的
/// </summary>
public abstract class House
{
/// <summary>
/// 房子的裝修方法--該操作相當(dāng)于Component類型的Operation方法
/// </summary>
public abstract void Renovation();
}
/// <summary>
/// MyHouse的房子,我要按我的要求做房子,相當(dāng)于ConcreteComponent類型
/// </summary>
public sealed class MyHouse : House
{
public override void Renovation()
{
Console.WriteLine("裝修我的房子");
}
}
裝飾類的定義
/// <summary>
/// 該抽象類就是裝飾接口的定義,該類型就相當(dāng)于是Decorator類型,如果需要具體的功能,可以子類化該類型
/// </summary>
public abstract class DecorationStrategy : House //關(guān)鍵點之二,體現(xiàn)關(guān)系為Is-a,有了這個關(guān)系,裝飾的類也可以繼續(xù)裝飾了
{
//通過組合方式引用Decorator類型,該類型實施具體功能的增加
//這是關(guān)鍵點之一,包含關(guān)系,體現(xiàn)為Has-a
protected House _house;
//通過構(gòu)造器注入,初始化平臺實現(xiàn)
protected DecorationStrategy(House house)
{
this._house = house;
}
//該方法就相當(dāng)于Decorator類型的Operation方法
public override void Renovation()
{
if (this._house != null)
{
this._house.Renovation();
}
}
}
安全需求類裝飾定義
/// <summary>
/// 具有安全功能的設(shè)備,可以提供監(jiān)視和報警功能,相當(dāng)于ConcreteDecoratorA類型
/// </summary>
public sealed class HouseSecurityDecorator : DecorationStrategy
{
public HouseSecurityDecorator(House house) : base(house) { }
public override void Renovation()
{
base.Renovation();
Console.WriteLine("增加安全系統(tǒng)");
}
}
保暖需求類裝飾定義
/// <summary>
/// 具有保溫接口的材料,提供保溫功能,相當(dāng)于ConcreteDecoratorB類型
/// </summary>
public sealed class KeepWarmDecorator : DecorationStrategy
{
public KeepWarmDecorator(House house) : base(house) { }
public override void Renovation()
{
base.Renovation();
Console.WriteLine("增加保溫的功能");
}
}
調(diào)用
public void RunTest()
{
//這就是我們需要裝飾的房子
House myselfHouse = new MyHouse();
DecorationStrategy securityHouse = new HouseSecurityDecorator(myselfHouse);
securityHouse.Renovation();
/*
* 此時房子就有了安全系統(tǒng)了.....
*/
//【1】如果我既要安全系統(tǒng)又要保暖呢,繼續(xù)裝飾就行
//DecorationStrategy securityAndWarmHouse = new KeepWarmDecorator(myselfHouse);
//securityAndWarmHouse.Renovation();
Console.WriteLine("\r\n*****************************\r\n");
//【2】如果我既要安全系統(tǒng)又要保暖呢,繼續(xù)裝飾就行【和上邊的進行運行比對】
//【對運行結(jié)果難理解的話,打斷點單步執(zhí)行進行理解】
DecorationStrategy securityAndWarmHouse1 = new KeepWarmDecorator(securityHouse);
securityAndWarmHouse1.Renovation();
}
裝飾模式的優(yōu)缺點
優(yōu)點
-
把抽象接口與其實現(xiàn)解耦。
-
抽象和實現(xiàn)可以獨立擴展,不會影響到對方。文章來源:http://www.zghlxwxcb.cn/news/detail-707725.html
-
實現(xiàn)細節(jié)對客戶透明,對用戶隱藏了具體實現(xiàn)細節(jié)。文章來源地址http://www.zghlxwxcb.cn/news/detail-707725.html
缺點
- 增加了系統(tǒng)的復(fù)雜度
到了這里,關(guān)于【23種設(shè)計模式】裝飾模式(九)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!