再說設計模式-裝飾模式

定義

裝飾模式(Decorator Pattern)的定義如下:

Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更爲靈活。

裝飾械的通用類圖如下:


在類圖中,有四個角色需要說明:

  • Component抽象構件
    Component是一個接口或者是抽象類,就是定義我們最核心的對象,也就是最原始的對象。
  • ConcreteComponent具體構件
    ConcreteComponent是最核心、最原始、最基本的接口或抽象類的實現,你要裝飾的就是它。
  • Decorator裝飾角色
    一般是一個抽象類,實現接口或者抽象方法,它裏面可不一定有抽象的方法,在它的屬性裏必然有一個private變量指向Component抽象構件。
  • 具體裝飾角色
    你要把你最核心的,最原始的、最基本的東西裝飾成其他東西。

抽象構件代碼:

public abstract class Component {
  // 抽象的方法
  public abstract void operate();
}

具體構件

public class ConcreteComponent extends Component {
  // 具體實現
  @Override
  public void operate() {
    System.out.println("do something");
  }
}

裝飾角色通常是一個抽象類,代碼如下:

public abstract class Decorator extends Component {
  private Component component = null;
  // 通過構造函數傳遞被修飾者
  public Decorator(Component _component) {
    this.component = _component;
  }

  //  委託給被修飾者執行
  @Override
  public void operate() {
    this.component.operate();
  }
}

具體的裝飾類:

public class ConcreteDecorator1 extends Decorator {
  // 定義被修飾者
  public ConcreteDecorator1(Component _component) {
    super(_component);
  }
  // 定義自己的修飾方法
  private void method1() {
    System.out.println("method1 修飾");
  }

  // 重寫父類的Operatio方法
  public void operate() {
    this.method();
    super.operate();
  }
}

場景類:

public class Client {
    public static void main(String[] args) {
      Component component = new ConcreteComponent();
      // 第一次修飾
      component = new ConcreteDecorator1(component);
      // 第二次修飾
      component = new ConcreteDecorator2(component);
      // 修飾後運行
      component.operate();
    }
}

優點

  • 裝飾類和被裝飾類可以獨立發展,而不會相互耦合;
  • 裝飾類是繼承關係的一個替代方案;
  • 裝飾模式可以動態地擴展一個實現類的功能;

缺點

多層的裝飾是比較複雜的。
爲什麼會複雜?
就如剝洋蔥一樣,你剝到最後才發現,是最裏層的裝飾出現了問題。
因此,儘量減少裝飾類的數量,以便降低系統的複雜度。

使用場景

  • 需要擴展一個類的功能,或給一個類增加附加功能。
  • 需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。
  • 需要爲一批的兄弟類進行改裝或加裝功能,當然是首選裝飾模式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章