人靠衣裝馬靠鞍
1.定義(官方的)
- 裝飾者模式可以動态地給一個對象增加其他職責。就擴充對象功能來說,裝飾者模式比生成子類更為靈活。
- The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.(有時候英文原版的比翻譯過來更容易了解)
2.類圖
-
Component類
定義對象接口,可以給這些動态地添加職責
-
ConcreteComponent類
定義具體的對象,Decorator類可以為其動态地添加職責
- Decorator類
- 維護一個指向Component對象執行個體的引用,并實作了與其一樣的接口
-
ConcreteDecorator類
定義了具體的裝飾類,給内部的具體對象添加職責
3. 代碼實作
3.1 Component類
abstract class Component{
//定義對象職責
public abstract void Operation();
}
3.2 ConcreteComponent類
public class ConcreteComponent extends Component{
@override
public void Operation(){
// do something
}
}
3.3 Decorator類
// 定義裝飾類,作為具體裝飾類的抽象接口
public abstract class Decorator extends Component{
// 指向Component執行個體的引用
protected Component component ;
public void setComponent(Component component){
this.component = component ;
}
@override
public void Operation(){
if( component != null){
//重寫Operation(),實際執行的是component的Operation()
component.Operation();
}
}
}
3.4 ConcreteDecorator類
public class ConcreteDecorator extents Decorator{
//具體的實作類中可以加入想要的屬性或方法
public void Operation(){
base.Operation(); //首先執行原Component對象的operation()
add(); //然後執行本類的裝飾行為,相當于對原component進行了裝飾
}
}
3.5 DecoratorTest類
public class DecoratorTest{
public static void main(String[] args){
ConcreteComponent cmp = new ConcreteComponent();
ConcreteDecoratorA cda = new ConcreteDecoratorA();
ConcreteDecoratorB cdb = new ConcreteDecoratorB();
cda.setComponent(cmp);
cdb.setComponent(cda);
cdb.Operation();// 執行順序:cmp.Operation()-->cda.Operation()-->cdb.Operation()
}
}
4.模式總結
- 裝飾模式利用setComponent()對對象程序封裝,使對象的實作和使用分離,每個被裝飾對象隻需關注自己的功能而不用關心自己是如何被加入對象鍊中。
- 裝飾模式對原系統中的核心功能或進行了很好的裝飾,在需要某種特殊的功能時裝飾模式可以很好地對要裝飾的對象進行包裝,在不需要時可以随時撤除。
- 裝飾模式适用于(但不一定都适用)以下情況
- 需要擴充一個類的功能,或給一個類添加附加職責。
- 需要動态的給一個對象添加功能,這些功能可以再動态的撤銷。
- 需要增加由一些基本功能的排列組合而産生的非常大量的功能,進而使繼承關系變的不現實。
- 當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴充,為支援每一種組合将産生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隐藏,或類定義不能用于生成子類。如下圖情況:
- 這樣的類圖組織看了之後,不瘋即傻。。。