裝飾模式(Decorate)是指在沒必要改變原類文件和使用繼承的狀況下,動態的擴展一個類的功能。它是經過建立一個包裝對象,也就是裝飾來包括真實的對象。包裹的方式通常是將原來的對象做爲裝飾類構造方法的參數,可是在不須要用到新功能的地方,它能夠直接調用原來的類中的方法。裝飾類必須和原來的類具備相同的接口。ide
裝飾模式中的角色以下:測試
1.抽象構件角色(Component)this
抽象構件角色給出一個抽象接口,以規範準備接收附加責任的對象。spa
2.具體構件角色(Concrete Component)設計
定義一個將要接收附加責任的類。code
3.裝飾角色(Decorate)component
持有一個構件對象的實例,並實現一個與抽象構件接口一致的接口。對象
4.具體裝飾角色(Concrete Decorate)blog
負責給構件對象添加附加的責任。繼承
裝飾模式的UML圖以下:
下面給出示例代碼:
1 public abstract class Component { 2 protected abstract void operation(); 3 }
1 public class ConcreteComponent extends Component { 2 @Override 3 protected void operation() { 4 System.out.println("do something in concreteComponent..."); 5 } 6 }
1 public abstract class Decorate extends Component{ 2 protected Component component; 3 4 protected void decorate(Component component){ 5 this.component = component; 6 } 7 }
1 public class ConcreteDecorateA extends Decorate { 2 3 @Override 4 protected void operation() { 5 //添加附加操做 6 System.out.println("do something in ConcreteDecorateA..."); 7 //調用被包裝類的方法 8 component.operation(); 9 } 10 11 }
1 public class ConcreteDecorateB extends Decorate { 2 3 @Override 4 protected void operation() { 5 //添加附加操做 6 System.out.println("do something in ConcreteDecorateB..."); 7 //調用被包裝類的方法 8 component.operation(); 9 } 10 11 }
下面給出測試代碼:
1 public class DecorateTest { 2 3 public static void main(String[] args) { 4 Component component = new ConcreteComponent(); 5 ConcreteDecorateA decorateA = new ConcreteDecorateA(); 6 ConcreteDecorateB decorateB = new ConcreteDecorateB(); 7 8 //將ConcreateComponent類包裝成ConcreteDecorateA 9 decorateA.decorate(component); 10 //將ConcreteDecorateA類包裝成ConcreteDecorateB 11 decorateB.decorate(decorateA); 12 13 decorateB.operation(); 14 } 15 16 }
運行結果以下:
總結:
1.裝飾模式的適用場景:
(1)須要擴展一個類的功能、或者給一個類添加附加的職責時。
(2)須要動態的給一個對象添加功能,這些功能能夠再動態的撤銷時。
(3)須要增長由一些基本功能的排列組合而產生的很是大量的功能,從而使繼承關係變得不現實。
(4)當不能採用生成子類的方式進行擴充時。
2.裝飾模式的優勢:
(1)裝飾模式與繼承關係的目的都是要擴展對象的功能,但裝飾模式能夠提供比繼承關係更大的靈活性。
(2)經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,能夠創造出不少不一樣行爲的組合。
3.裝飾模式的缺點:
(1)裝飾模式比繼承關係更加靈活,但意味着更加複雜。
(2)裝飾模式會致使設計中出現不少小類,若是過分使用會使程序變得很複雜。
4.裝飾模式與適配器模式的區別:
(1)關於新職責
適配器模式也能夠再轉換時增長新的功能,但主要目的是爲了完成接口的兼容。裝飾模式最主要的職責是給裝飾類增長新的職責。
(2)關於原接口
適配器模式是用新接口來調用原接口,原接口對新系統來講是不可見或者不可用的。裝飾模式原封不動的調用原接口,系統對裝飾的對象也是經過原接口來完成使用。
(3)關於裝飾的對象
適配器是知道被適配者的詳細狀況的,而裝飾者只知道其接口是什麼,至於什麼具體類型只有在運行期間才知道。