設計模式(八)裝飾模式

WellBay 2月前


標籤:之一   程式   tor   str   建構函式   情況   彈性   static   ima   

1、意圖

  動態給一個物件新增一些額外的職責。比如增加功能,裝飾模式相比生成子類更為靈活。該模式以對客戶端透明的方式擴充套件物件的功能。

 

2、適用場景

(1)在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責;

(2)當不能採用繼承方式對系統進行擴充套件或者採用繼承不利於系統的擴充套件和維護時,第一種情況,可能有大量獨立的擴充套件,為支援每一種組合將產生大量的子類,使得子類數目呈現爆炸式增長;另外一種情況可能是因為類的定義被隱藏,如@Hide註釋的類,或者定義的類不能生成子類,如final修飾的類;

(3)需要動態地給某個物件新增功能,這些功能也可以動態地撤銷。

 

3、類圖分析

 

 

 

  1.  Component:定義一個物件介面,可以給這些物件動態地新增職責。
  2. ConcreteComponent:定義一個物件,可以給這個物件新增一下職責。
  3. Decorator:維持一個指向Component物件的引用。一般也會直接實現Component介面,以達到相同父型別的目的。
  4. ConcreteDecorator:向元件新增職責。

 

4、程式碼示例

1 /**
2  * @author it-小林
3  * @desc 被修飾的類的抽象介面
4  * @date 2021年07月28日 11:28
5  */
6 public interface People {
7     public void run();
8 }
/**
 * @author it-小林
 * @desc 被修飾的類
 * @date 2021年07月28日 11:28
 */
public class Man implements People{
    @Override
    public void run() {
        System.out.println("人會跑步");
    }
}

 

 1 /**
 2  * @author it-小林
 3  * @desc 裝飾的抽象類
 4  * @date 2021年07月28日 11:29
 5  */
 6 public class AbstractDecorator implements People{
 7     //持有被裝飾類的引用
 8     private People people;
 9 
10     //建構函式注入被修飾者
11 
12 
13     public AbstractDecorator(People people) {
14         this.people = people;
15     }
16 
17     @Override
18     public void run() {
19         people.run();
20     }
21 }
 1 /**
 2  * @author it-小林
 3  * @desc 裝飾類
 4  * @date 2021年07月28日 11:33
 5  */
 6 public class ManDecorator extends AbstractDecorator{
 7 
 8     public ManDecorator(People people) {
 9         super(people);
10     }
11 
12     //裝飾類增加的功能
13     private void sing(){
14         System.out.println("人在唱歌");
15     }
16 
17     @Override
18     public void run() {
19         super.run();
20         sing();
21     }
22 }
 1 /**
 2  * @author it-小林
 3  * @desc
 4  * @date 2021年07月28日 11:35
 5  */
 6 public class Client {
 7     public static void main(String[] args) {
 8         //建立被修飾的類
 9         People man = new Man();
10 
11         //建立修飾的類,並新增被修飾類的引用
12         People superMan = new ManDecorator(man);
13 
14         //執行增強後的run方法
15         superMan.run();
16 
17     }
18 }

 

 

5、優缺點

優點:

  1. 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合;
  2. Decorator模式與繼承關係的目的都是要擴充套件物件的功能,但是Decorator可以提供比繼承更多的靈活性。

缺點:

  1. 裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出最佳選擇;
  2. 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜;
  3. 這種比繼承更加靈活機動的特性,也同時意味著更加多的複雜性。

 

6、總結

  • 繼承屬於擴充套件形式之一,但不見得是達到彈性設計的最佳方案;
  • 組合和委託可用於在執行時動態地加上新的行為;
  • 在我們的設計中,應該允許行為可以被擴充套件,而不須修改現有的程式碼;
  • 裝飾者模式意味著一群裝飾者類, 這些類用來包裝具體元件;
  • 裝飾者一般對組建的客戶是透明的,除非客戶程式依賴於元件的具體型別;
  • 可以有無數個裝飾者包裝一個元件;
  • 裝飾者類反映出被裝飾的元件型別(實際上,他們具有相同的型別,都經過介面或繼承實現);
  • 裝飾者可以在被裝飾者的行為前面與/或後面加上自己的行為,甚至將被裝飾者的行為整個取代掉,而達到特定的目的。

 7、模式對比

  1. 介面卡(Adapter)模式:裝飾模式不同於介面卡模式,介面卡模式會給物件一個全新的介面,而裝飾模式是改變物件的職責,並不會改變物件介面;
  2. 組合(Composite)模式:可以將裝飾裝飾模式視為一個退化的、僅有一個元件的組合(示例中調料類儲存了一個咖啡的引用)。然而,裝飾僅給物件新增一些額外的職責—它的目的不在於物件聚集;
  3. 策略(Strategy)模式:裝飾模式主要改變的物件的外表;而策略模式重點在於改變物件的核心。它們是改變物件的兩種途徑。

設計模式(八)裝飾模式

標籤:之一   程式   tor   str   建構函式   情況   彈性   static   ima   

原文地址:https://www.cnblogs.com/linruitao/p/15067811.html


上一篇:HCNA Routing&Switching之OSPF度量值和基礎配置命令總結
下一篇:你有沒有亂用“leader”,擔當是個好東西