日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

23装饰模式(Decorator Pattern)

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 23装饰模式(Decorator Pattern) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

子類復子類,子類何其多

??? 假如我們需要為游戲中開發一種坦克,除了各種不同型號的坦克外,我們還希望在不同場合中為其增加以下一種或多種功能;比如紅外線夜視功能,比如水陸兩棲功能,比如衛星定位功能等等。
按類繼承的作法如下:
???

1??//抽象坦克
2??public?abstract?class?Tank
3?????{
4????????public?abstract?void?Shot();
5????????public?abstract?void?Run();
6?????}

各種型號:

?1?//T50型號
?2????public?class?T50:Tank
?3?????{
?4?????????public?override?void?Shot()
?5?????????{
?6?????????????Console.WriteLine("T50坦克平均每秒射擊5發子彈");
?7?????????}
?8?????????public?override?void?Run()
?9?????????{
10?????????????Console.WriteLine("T50坦克平均每時運行30公里");
11?????????}
12?????}

?

?1?//T75型號?
?2??public?class?T75?:?Tank
?3?????{
?4?????????public?override?void?Shot()
?5?????????{
?6?????????????Console.WriteLine("T75坦克平均每秒射擊10發子彈");
?7?????????}
?8?????????public?override?void?Run()
?9?????????{
10?????????????Console.WriteLine("T75坦克平均每時運行35公里");
11?????????}
12?????}

?

?1?//T90型號??
?2??public?class?T90?:Tank
?3?????{
?4?????????public?override?void?Shot()
?5?????????{
?6?????????????Console.WriteLine("T90坦克平均每秒射擊10發子彈");
?7?????????}
?8?????????public?override?void?Run()
?9?????????{
10?????????????Console.WriteLine("T90坦克平均每時運行40公里");
11?????????}
12?????}

各種不同功能的組合:比如IA具有紅外功能接口、IB具有水陸兩棲功能接口、IC具有衛星定位功能接口。
?

?1?//T50坦克各種功能的組合
?2?public?class?T50A:T50,IA
?3?{
?4???//具有紅外功能
?5?}
?6?public?class?T50B:T50,IB
?7?{
?8??//具有水陸兩棲功能
?9?}
10?public?class?T50C:T50,IC
11?{
12?
13?}
14?public?class?T50AB:T50,IA,IB
15?{}
18?public?class?T50AC:T50,IA,IC
19?{}
20?public?class?T50BC:T50,IB,IC
21?{}
22?public?class?T50ABC:T50,IA,IB,IC
23?{}

?

?1?
?2???//T75各種不同型號坦克各種功能的組合
?3???public?class?T75A:T75,IA
?4???{
?5?????//具有紅外功能
?6???}
?7???public?class?T75B:T75,IB
?8???{
?9????//具有水陸兩棲功能
10???}
11??public?class?T75C:T75,IC
12??{
13????//具有衛星定位功能
14??}
15??public?class?T75AB:T75,IA,IB
16??{
17???//具有紅外、水陸兩棲功能
18?}
19??public?class?T75AC:T75,IA,IC
20??{
21???//具有紅外、衛星定位功能
22?}
23??public?class?T75BC:T75,IB,IC
24??{
25??//具有水陸兩棲、衛星定位功能
26?}
27??public?class?T75ABC:T75,IA,IB,IC
28??{
29???//具有紅外、水陸兩棲、衛星定位功能
30?}

?

?1?
?2???//T90各種不同型號坦克各種功能的組合
?3???public?class?T90A:T90,IA
?4???{
?5?????//具有紅外功能
?6???}
?7???public?class?T90B:T90,IB
?8???{
?9????//具有水陸兩棲功能
10???}
11??public?class?T90C:T90,IC
12??{
13????//具有衛星定位功能
14??}
15??public?class?T90AB:T90,IA,IB
16??{
17???//具有紅外、水陸兩棲功能
18?}
19??public?class?T90AC:T90,IA,IC
20??{
21???//具有紅外、衛星定位功能
22?}
23??public?class?T90BC:T90,IB,IC
24??{
25??//具有水陸兩棲、衛星定位功能
26?}
27??public?class?T90ABC:T90,IA,IB,IC
28??{
29???//具有紅外、水陸兩棲、衛星定位功能
30?}

由此可見,如果用類繼承實現,子類會爆炸式地增長。
動機(Motivate):
??? 上述描述的問題根源在于我們“過度地使用了繼承來擴展對象的功能”,由于繼承為類型引入的靜態物質,使得這種擴展方式缺乏靈活性;并且隨著子類的增多(擴展功能的增多),各種子類的組合(擴展功能組合)會導致更多子類的膨脹(多繼承)。
???如何使“對象功能的擴展”能夠根據需要來動態地實現?同時避免“擴展功能的增多”帶來的子類膨脹問題?從而使得任何“功能擴展變化”所導致的影響將為最低?
意圖(Intent):
??? 動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更為靈活。
??? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??? ------《設計模式》GOF
結構圖(Struct):
??? ?????????????



生活中的例子:
??? ?? ? ? ? ? ? ? ? ?? ???

適用性:
??? 需要擴展一個類的功能,或給一個類增加附加責任。

??? 需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。

??? 需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關系變得不現實。

實現代碼:
????

1?namespace?Decorator
2?{
3???public?abstract?class?Tank
4?????{
5????????public?abstract?void?Shot();
6????????public?abstract?void?Run();
7?????}
8?}

?

?1?namespace?Decorator
?2?{
?3????public?class?T50:Tank
?4?????{
?5?????????public?override?void?Shot()
?6?????????{
?7?????????????Console.WriteLine("T50坦克平均每秒射擊5發子彈");
?8?????????}
?9?????????public?override?void?Run()
10?????????{
11?????????????Console.WriteLine("T50坦克平均每時運行30公里");
12?????????}
13?????}
14?}

?

?1?namespace?Decorator
?2?{
?3?????public?class?T75?:?Tank
?4?????{
?5?????????public?override?void?Shot()
?6?????????{
?7?????????????Console.WriteLine("T75坦克平均每秒射擊10發子彈");
?8?????????}
?9?????????public?override?void?Run()
10?????????{
11?????????????Console.WriteLine("T75坦克平均每時運行35公里");
12?????????}
13?????}
14?}

?

?1?namespace?Decorator
?2?{
?3?????public?class?T90?:Tank
?4?????{
?5?????????public?override?void?Shot()
?6?????????{
?7?????????????Console.WriteLine("T90坦克平均每秒射擊10發子彈");
?8?????????}
?9?????????public?override?void?Run()
10?????????{
11?????????????Console.WriteLine("T90坦克平均每時運行40公里");
12?????????}
13?????}
14?}

?

?1?namespace?Decorator
?2?{
?3????public?abstract?class?Decorator?:Tank?//Do?As?接口繼承?非實現繼承
?4?????{
?5????????private?Tank?tank;?//Has?a??對象組合
?6????????public?Decorator(Tank?tank)
?7????????{
?8????????????this.tank?=?tank;
?9????????}
10????????public?override?void?Shot()
11????????{
12????????????tank.Shot();
13????????}
14????????public?override?void?Run()
15????????{
16????????????tank.Run();
17????????}
18?????}
19?}
20?

?

?1?
?2?namespace?Decorator
?3?{
?4????public?class?DecoratorA?:Decorator
?5?????{
?6????????public?DecoratorA(Tank?tank)?:?base(tank)
?7????????{
?8????????}
?9???????public?override?void?Shot()
10???????{
11??????????//Do?some?extension?//功能擴展?且有紅外功能
12???????????base.Shot();
13???????}
14?????public?override?void?Run()
15?????{
16?
17?????????base.Run();
18?????}
19?????}
20?}

?

?1?namespace?Decorator
?2?{
?3?????public?class?DecoratorB?:Decorator
?4?????{
?5???????public?DecoratorB(Tank?tank)?:?base(tank)
?6????????{
?7????????}
?8???????public?override?void?Shot()
?9???????{
10??????????//Do?some?extension?//功能擴展?且有水陸兩棲功能
11??????????base.Shot();
12???????}
13?????public?override?void?Run()
14?????{
15?
16?????????base.Run();
17?????}
18????}????
19?}
20?

?

?1?namespace?Decorator
?2?{
?3?????public?class?DecoratorC?:Decorator
?4?????{
?5????????public?DecoratorC(Tank?tank)?:?base(tank)
?6????????{
?7????????}
?8???????public?override?void?Shot()
?9???????{
10??????????//Do?some?extension?//功能擴展?且有衛星定位功能
11??????????base.Shot();
12???????}
13?????public?override?void?Run()
14?????{
15?
16?????????base.Run();
17?????}?
18?????????
19????}
20?}

?

?1????class?Program
?2?????{
?3?????????static?void?Main(string[]?args)
?4?????????{
?5?????????????Tank?tank?=?new?T50();
?6?????????????DecoratorA?da?=?new?DecoratorA(tank);?//且有紅外功能
?7?????????????DecoratorB?db?=?new?DecoratorB(da);???//且有紅外和水陸兩棲功能
?8?????????????DecoratorC?dc?=?new?DecoratorC(db);???//且有紅外、水陸兩棲、衛星定們三種功能
?9?????????????dc.Shot();
10?????????????dc.Run();
11?????????}
12?????}


Decorator模式的幾個要點:
??? 通過采用組合、而非繼承的手法,Decorator模式實現了在運行時動態地擴展對象功能的能力,而且可以
根據需要擴展多個功能。避免了單獨使用繼承帶來的“靈活性差"和"多子類衍生問題"。
??? Component類在Decorator模式中充當抽象接口的角色,不應該去實現具體的行為。而且Decorator類對于Component類應該透明---換言之Component類無需知道Decorator類,Decorator類是從外部來擴展Component類的功能。
??? Decorator類在接口上表現為is-a Component的繼承關系,即Decorator類繼承了Component類所且有的接口。但在實現上又表現has a Component的組合關系,即Decorator類又使用了另外一個Component類。我們可以使用一個或者多個Decorator對象來“裝飾”一個Component對象,且裝飾后的對象仍然是一個Component對象。
??? Decorator模式并非解決”多子類衍生的多繼承“問題,Decorator模式應用的要點在于解決“主體
類在多個方向上的擴展功能”------是為“裝飾”的含義。

Decorator在.NET(Stream)中的應用:
?????

可以看到,?BufferedStream和CryptoStream其實就是兩個包裝類,這里的Decorator模式省略了抽象裝飾角色(Decorator),示例代碼如下:

?1?class?Program
?2?
?3?{
?4?
?5?????public?static?void?Main(string[]?args)
?6?
?7?????{
?8?
?9?????????MemoryStream?ms?=
10?
11?????????????new?MemoryStream(new?byte[]?{?100,456,864,222,567});
12?
13??
14?
15?????????//擴展了緩沖的功能
16?
17?????????BufferedStream?buff?=?new?BufferedStream(ms);
18?
19??
20?
21?????????//擴展了緩沖,加密的功能
22?
23?????????CryptoStream?crypto?=?new?CryptoStream(buff);
24?
25?????}
26?
27?}


通過反編譯,可以看到BufferedStream類的代碼(只列出部分),它是繼承于Stream類:

?1?public?sealed?class?BufferedStream?:?Stream
?2?
?3?{
?4?
?5?????//?Methods
?6?
?7?????private?BufferedStream();
?8?
?9?????public?BufferedStream(Stream?stream);
10?
11?????public?BufferedStream(Stream?stream,?int?bufferSize);
12?
13?????//?Fields
14?
15?????private?int?_bufferSize;
16?
17?????private?Stream?_s;
18?
19?}

總結

以上是生活随笔為你收集整理的23装饰模式(Decorator Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。