裝飾器模式
更多設計模式小故事案例程式碼詳解 >>點我!點我!點我!<< 設計模式,如此簡單~
所屬型別: 結構型
標籤:
- 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!
複製程式碼
適用契機
- 擴充套件一個類的功能。
- 動態增加功能,動態撤銷。
- 通過子類的擴充套件是不切實際的。有時,大量的獨立擴充套件是可能的,並且會產生大量子類來支援每個組合。或者類定義可以隱藏或不可用於子類化。
相關教程
實際應用
- java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer
- java.util.Collections#synchronizedXXX()
- java.util.Collections#unmodifiableXXX()
- java.util.Collections#checkedXXX()