设计模式之装饰模式详解(附应用举例实现)
文章目錄
- 1 裝飾模式介紹
- 2 裝飾模式詳解
- 2.1 裝飾模式結構
- 2.2 裝飾模式實現
- 2.3 裝飾模式應用舉例
- 3 透明裝飾模式和半透明裝飾模式
1 裝飾模式介紹
在生活中,我們往往會給圖片增加一些邊框等來裝飾圖片,可以讓圖片變得更漂亮,如下圖,就是對小狗圖片的裝飾。
在軟件設計中,我們也有一種類似圖片的技術可以對已有對象(圖片)的功能進行擴展(裝修),以獲得更加符合用戶需求的對象,使得對象具有更加強大的功能。這種技術對應于一種被稱之為裝飾模式(Decorator Pattern)的設計模式。裝飾模式能動態地給一個對象增加一些額外的職責。就擴展功能而言,裝飾模式提供了一種比使用子類更加靈活的替代方案。引入了裝飾類,在裝飾類中既可以調用待裝飾的原有類的方法,還可以增加新的方法,以擴展原有類的功能
主要解決: 一般的,我們為了擴展一個類經常使用繼承方式實現,由于繼承為類引入靜態特征,并且隨著擴展功能的增多,子類會很膨脹。
何時使用: 在不想增加很多子類的情況下擴展類。
如何解決: 將具體功能職責劃分,同時繼承裝飾者模式。
關鍵代碼: 1、Component 類充當抽象角色,不應該具體實現。 2、修飾類引用和繼承 Component 類,具體擴展類重寫父類方法。
應用實例: 1、孫悟空有 72 變,當他變成"廟宇"后,他的根本還是一只猴子,但是他又有了廟宇的功能。 2、不論一幅畫有沒有畫框都可以掛在墻上,但是通常都是有畫框的,并且實際上是畫框被掛在墻上。在掛在墻上之前,畫可以被蒙上玻璃,裝到框子里;這時畫、玻璃和畫框形成了一個物體。
優點: 裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實現類的功能。
缺點: 多層裝飾比較復雜。
使用場景: 1、擴展一個類的功能。 2、動態增加功能,動態撤銷。
注意事項: 可代替繼承。
2 裝飾模式詳解
2.1 裝飾模式結構
裝飾模式的結構如圖所示:
由結構圖可知,裝飾模式包含以下4個角色。
2.2 裝飾模式實現
抽象構件類典型代碼:
public abstract class Component {public abstract void operation(); }具體構件類典型代碼:
public class ConcreteComponent extends Component {public void operation() {//實現基本功能 } }抽象裝飾類典型代碼:
public class Decorator extends Component {private Component component; //維持一個對抽象構件對象的引用//注入一個抽象構件類型的對象public Decorator(Component component) {this.component=component;}public void operation() {component.operation(); //調用原有業務方法} }具體裝飾類典型代碼:
public class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component); }public void operation() {super.operation(); //調用原有業務方法addedBehavior(); //調用新增業務方法}//新增業務方法public void addedBehavior() { ……} }2.3 裝飾模式應用舉例
-
題目描述
簡單的手機(SimplePhone)再接收到來電的時候,會發出聲音提醒主人;而現在我們需要為該手機添加一項功能,在接收來電的時候,除了聲音還能產生振動(JarPhone);還可以得到更高級的手機(ComplexPhone),來電的時候,它不僅能夠發聲,產生振動,而且還有燈光在閃爍提示。現在用裝飾模式來模擬一下手機的升級過程,要求繪制類圖并編程實現。
-
UML類圖
其中,Cellphone 為抽象類,聲明了來電方法 receiveCall(),SimplePhone 為簡單手機類,
提供了聲音提示,JarPhone 和 ComplexPhone 分別提供了振動提示和燈光閃爍提示。
PhoneDecorator 是抽象裝飾者,它維持一個對父類對象的引用。
-
代碼
代碼地址
3 透明裝飾模式和半透明裝飾模式
透明裝飾模式
要求客戶端完全針對抽象編程,裝飾模式的透明性要求客戶端程序不應該將對象聲明為具體構件類型或具體裝飾類型,而應該全部聲明為抽象構件類型。對于客戶端而言,具體構件對象和具體裝飾對象沒有任何區別。可以讓客戶端透明地使用裝飾之前的對象和裝飾之后的對象,無須關心它們的區別。可以對一個已裝飾過的對象進行多次裝實例:
…… Component component_o,component_d1,component_d2; //全部使用抽象構件定義 component_o = new ConcreteComponent(); component_d1 = new ConcreteDecorator1(component_o); component_d2 = new ConcreteDecorator2(component_d1); component_d2.operation(); //無法單獨調用component_d2的addedBehavior()方法 ……半透明裝飾模式
用具體裝飾類型來定義裝飾之后的對象,而具體構件使用抽象構件類型來定義。對于客戶端而言,具體構件類型無須關心,是透明的;但是具體裝飾類型必須指定,這是不透明的。可以給系統帶來更多的靈活性,設計相對簡單,使用起來也非常方便,客戶端使用具體裝飾類型來定義裝飾后的對象,因此可以單獨調用addedBehavior()方法。最大的缺點在于不能實現對同一個對象的多次裝飾,而且客戶端需要有區別地對待裝飾之前的對象和裝飾之后的對象。實例:
…… Component component_o; //使用抽象構件類型定義 component_o = new ConcreteComponent(); component_o.operation(); ConcreteDecorator component_d; //使用具體裝飾類型定義 component_d = new ConcreteDecorator(component_o); component_d.operation(); component_d.addedBehavior(); //單獨調用新增業務方法 ……總結
以上是生活随笔為你收集整理的设计模式之装饰模式详解(附应用举例实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微前端实践--webpack5模块联邦
- 下一篇: asp.net ajax控件工具集 Au