Java 設計模式(五)《裝飾器模式》

lvgo發表於2018-08-23

裝飾器模式

更多設計模式小故事案例程式碼詳解 >>點我!點我!點我!<< 設計模式,如此簡單~


所屬型別: 結構型

標籤:

  • Java
  • Gang Of Four
  • Difficulty-Beginner(入門級難度)

注:

什麼是 GOF(四人幫,全拼 Gang of Four)? 在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名為 Design Patterns - Elements of Reusable Object-Oriented Software(中文譯名:設計模式 - 可複用的物件導向軟體元素) 的書,該書首次提到了軟體開發中設計模式的概念。 四位作者合稱 GOF(四人幫,全拼 Gang of Four)。他們所提出 對介面程式設計而不是對實現程式設計。 優先使用物件組合而不是繼承。

別名

Wrapper(包裝器) (介面卡模式(Adapter Pattern)和裝飾器模式(Decorator Pattern)的統稱)

意圖

動態地給一個物件新增一些額外的職責。就增加功能來說,裝飾器模式相比生成子類更為靈活。

釋義

小故事案例

有一隻怪獸,它平時的時候赤手空拳,攻擊力有10.如果要攻擊力到20需要一把武器,現在我們不需要重新找一個有武器的怪獸,只需要給現在的怪獸增加10攻擊就可以了.

簡單來說

裝飾器模式可以在裝飾器類中通過裝飾,來動態的改變被裝飾類的行為

維基百科這樣說

在物件導向程式設計中,裝飾器模式是一種設計模式,它允許靜態或動態地將行為新增到單個物件,而不影響來自同一類的其他物件的行為。裝飾模式對於堅持單一的責任原則通常是有用的,因為它允許功能在具有獨特關注區域的類之間進行劃分。


程式碼詳解

我們有一個小怪獸介面和一個簡單的小怪獸

public interface Troll {
  void attack();
  int getAttackPower();
  void fleeBattle();
}

public class SimpleTroll implements Troll {

  private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTroll.class);

  @Override
  public void attack() {
    LOGGER.info("The troll tries to grab you!");
  }

  @Override
  public int getAttackPower() {
    return 10;
  }

  @Override
  public void fleeBattle() {
    LOGGER.info("The troll shrieks in horror and runs away!");
  }
}
複製程式碼

接著我們通過一個裝飾類來動態的裝飾我們的小怪獸

public class ClubbedTroll implements Troll {

  private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class);

  private Troll decorated;

  public ClubbedTroll(Troll decorated) {
    this.decorated = decorated;
  }

  @Override
  public void attack() {
    decorated.attack();
    LOGGER.info("The troll swings at you with a club!");
  }

  @Override
  public int getAttackPower() {
    return decorated.getAttackPower() + 10;
  }

  @Override
  public void fleeBattle() {
    decorated.fleeBattle();
  }
}
複製程式碼

裝飾前後

// simple troll
Troll troll = new SimpleTroll();
troll.attack(); // The troll tries to grab you!
troll.fleeBattle(); // The troll shrieks in horror and runs away!

// change the behavior of the simple troll by adding a decorator
troll = new ClubbedTroll(troll);
troll.attack(); // The troll tries to grab you! The troll swings at you with a club!
troll.fleeBattle(); // The troll shrieks in horror and runs away!
複製程式碼

更多完整程式碼點此檢視


適用契機

  • 擴充套件一個類的功能。
  • 動態增加功能,動態撤銷。
  • 通過子類的擴充套件是不切實際的。有時,大量的獨立擴充套件是可能的,並且會產生大量子類來支援每個組合。或者類定義可以隱藏或不可用於子類化。

相關教程


實際應用

參考文獻

相關文章