定義
裝飾模式是爲已有功能動態地添加更多功能的一種方式。
介紹
由定義,給一個類或對象添加功能,爲了不破壞類的結構,可以有兩種方式:
- 繼承 使用繼承機制是給現有類添加功能的一種有效途徑,通過繼承一個現有類可以使得子類在擁有自身方法的同時還擁有父類的方法。但是這種方法是靜態的,用戶不能控制增加行爲的方式和時機。
- 關聯 將一個類的對象嵌入另一個對象中,由另一個對象來決定是否調用嵌入對象的行爲以便擴展自己的行爲,我們稱這個嵌入的對象爲裝飾器(Decorator)
UML
示例代碼
abstract class Component { public abstract void Operation(); } public class ConcreateComponent extends Component { @Override public void Operation() { // TODO Auto-generated method stub System.out.println("basic operation"); } } public class Decorator extends Component { protected Component component; public void SetComponent(Component component) { this.component = component; } @Override public void Operation() { // TODO Auto-generated method stub if (component != null) { component.Operation(); } } } public class DecoratorA extends Decorator { @Override public void Operation() { // TODO Auto-generated method stub super.Operation(); newBehavior(); } private void newBehavior() { System.out.println("Add new behavior AAA"); } } public class DecoratorB extends Decorator { @Override public void Operation() { // TODO Auto-generated method stub super.Operation(); newBehavior(); } private void newBehavior() { System.out.println("Add new behavior BBB"); } } public static void main(String[] args) { // TODO Auto-generated method stub ConcreateComponent c = new ConcreateComponent(); DecoratorA a = new DecoratorA(); DecoratorB b = new DecoratorB(); a.SetComponent(c); a.Operation(); b.SetComponent(a); b.Operation(); } //輸出 basic operation Add new behavior AAA basic operation Add new behavior AAA Add new behavior BBB
基本思路是,在ConcreateComponent做一些基本操作,然後創建裝飾器,如果需要給對象增加新的特性,就把該對象放入對應的裝飾器中。
儘量保持Component作爲一個輕類,不要做太多邏輯。
評價
優缺點
優點
- 不會破壞類的封裝性,而且耦合性比繼承要低,靈活性比繼承高。
- 可以動態的拓展一個對象的功能。
- 可以用多個裝飾器按照不同順序組合出不同的對象。
- 具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類。符合開閉原則。
缺點
- 需要創建更多的對象。
- 因爲裝飾器使用靈活,使用的順序也能不同,可能引起的錯誤會比較隱蔽。
使用場景
當系統需要新功能的時候,如果新功能只是爲了滿足某個條件下才會執行的行爲,則不建議修改原類,而是使用裝飾模式,把要裝飾的功能放在特定類中,然後用這個類包裝它所要裝飾的對象。這樣,客戶代碼可以根據情況在運行時選擇裝飾功能包裝對象。