天天看點

【設計模式】——結構類型模式——裝飾模式

裝飾模式

動态地給對象增加額外的職責,且可以多次增加

動機

給相片套多個相片框

定義

  1. 對象結構型模式
  2. 透明動态地給一個對象增加一些額外的職責
  3. 不需要建立更多子類的情況下可以擴充功能

結構

抽象建構類:抽象出具體建構的功能

具體建構:照片,繼承抽象構件

抽象裝飾:繼承/實作抽象構件或者聚合抽象建構,

​ 維持一個對抽象構件對象的引用(定義一個聲明抽象構件)

具體裝飾:具體增加的什麼功能

【設計模式】——結構類型模式——裝飾模式

分析

透明裝飾模式

  1. 完全針對抽象,全部聲明為抽象構件類型,用戶端完全使用抽象構件的聲明
  2. 對于用戶端而言,具體構對象和具體裝飾對象沒有差別,都是抽象構件聲明的
  3. 可以透明使用裝飾前和裝飾後的對象,無需關心差別,裝飾後的對象是新的對象,但由于繼承抽象構件,是以看作是具體構件
  4. 可以多次裝飾
  5. 無法在用戶端獨立調用新增的方法
【設計模式】——結構類型模式——裝飾模式

不透明裝飾模式

  1. 用具體裝飾類型定義裝飾後的對象,具體建構使用抽象構件類型來定義
  2. 對用戶端而言,具體構件類型是透明的,由抽象構件類型進行聲明,但具體裝飾類型必須指定,非透明
  3. 可以單獨調用新增的方法
  4. 不能重複裝飾,且用戶端需要差别對待裝飾前後的對象——

    裝飾前是抽象構件類型,裝飾後是具體裝飾類型

【設計模式】——結構類型模式——裝飾模式

執行個體

【設計模式】——結構類型模式——裝飾模式
【設計模式】——結構類型模式——裝飾模式

Transform類

public interface Transform
{
   public void move();
}
           

Changer類

public class Changer implements Transform
{
   private Transform transform;
   
   public Changer(Transform transform)
   {
      this.transform=transform;
   }
   
   public void move()
   {
      transform.move();  
   }
}
           

Car類

public final class Car implements Transform
{
   public Car()
   {
      System.out.println("變形金剛是一輛車!");
   }
   
   public void move()
   {
      System.out.println("在陸地上移動!"); 
   }
}
           

Robot類

public class Robot extends Changer
{
   public Robot(Transform transform)
   {
      super(transform);
      System.out.println("變成機器人!");
   }
   
   public void say()
   {
      System.out.println("說話!"); 
   }
}
           

Client類

public class Client
{
   public static void main(String args[])
   {
      Transform camaro;
      camaro=new Car();
      camaro.move();
      System.out.println("-----------------------------");
      
      Airplane bumblebee=new Airplane(camaro);
      bumblebee.move();
      bumblebee.fly();
   }
}
           

運作結果

【設計模式】——結構類型模式——裝飾模式

優點

  1. 擴充對象的時候更加靈活,不會急劇增加類的個數
  2. 可以通過配置檔案完成對象功能的擴充
  3. 可以多次裝飾
  4. 可以根據需求增加新的具體構件類和具體裝飾類:給新照片買新的相框

缺點

  1. 會産生很多小對象:
    1. 具體裝飾類
    2. 多次裝飾時,裝飾過程的中間對象
  2. 比繼承更容易出錯,排錯也困難

适用場景

  1. 動态透明給對象添加職責
  2. 不能采用繼承的方式對系統進行擴充或者采用繼承時不利于系統的擴充和維護