概念:
裝飾者模式又稱為包裝(wrapper)模式。裝飾者模式對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案。
結構:
裝飾者模式以透明的方式給一個對象附加上更多的責任,換而言之,客戶端並不會覺得對象在裝飾前后有什么不同,裝飾者模式可以在不使用創造更多子類的情況下,將對象的功能拓展。
結構圖:
角色分析:
抽象構件(Component)角色:給出一個抽象接口,以規范准備接受附加責任的對象。
具體構件(ConCreteComponent)角色:定義一個將要接受附加責任的類。
裝飾(Decorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件接口一致的接口。
具體裝飾(ConcreteDecorator)角色:負責給構件對象“貼上”附加的責任。
代碼:
抽象構建角色:

public interface Component { public void sampleOperation(); }
具體構件角色:

public class ConcreteComponent implements Component { @Override public void sampleOperation() { // 寫相關的業務代碼
} }
裝飾者角色:

public class Decorator implements Component{ private Component component; public Decorator(Component component){ this.component = component; } @Override public void sampleOperation() { // 委派給構件
component.sampleOperation(); } }
具體裝飾者角色:
public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void sampleOperation() { super.sampleOperation(); // 寫相關的業務代碼
} }
//B組件類似
具體示例
有工人接口,我們定義了鐵匠,現在要對鐵匠進行不同的技能強化。
工人接口:

public interface Worker { void working(); }
鐵匠實現類:

public class Smith implements Worker { private String name; private int age; public Smith(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public void working() { System.out.println("我是一個鐵匠"); } }
技能實現類:

public class Skill implements Worker { private Worker worker; public Skill(Worker worker) { this.worker = worker; } @Override public void working() { worker.working(); } //為半透明模式做的拓展 public void heating(){} }
具體的技能類1:

public class Hardening extends Skill { public Hardening(Worker worker) { super(worker); } @Override public void working() { System.out.println("我在淬火"); } }
具體的技能類2:

public class Beat extends Skill { public Beat(Worker worker) { super(worker); } @Override public void working() { System.out.println("我在反復地捶打"); } }
補充:
裝飾者模式的簡化
1.去掉接口的形式,直接繼承自要被裝飾的類即可。
2.直接使用實現接口的形式實現裝飾,而不用再額外加一層繼承關系。適用於只有一個強化關系的情況
透明度的要求:
裝飾者模式要求程序不應該聲明需要被裝飾的實體類,而是應該聲明抽象接口。
用示例中的聲明表示就是下面這樣:
即所有的人,都是工人,鐵匠是工人,會淬火的鐵匠也是工人。

Worker worker1 = new Smith("李鐵蛋",18); Worker worker2 = new Hardening(worker1);
半透明的裝飾模式:
當發現工人接口並不能滿足所有的要求的時候,要想實現透明度要求,必須在接口中添加新方法,所以很多實現的裝飾者模式都是采取“半透明”的方式,即裝飾者類可以對接口進行拓展,同時聲明的時候,可以選擇以裝飾者類為准。
本例中,裝飾者類就是技能類,我們為淬火技能類添加加熱方法

Worker worker = new Smith("李狗蛋",18); Hardening smith = new Hardening(worker); smith.heating();
半透明的裝飾者模式是介於裝飾者模式跟適配器模式中的,適配器模式的思路是改變接口,也可以通過改寫或新增方法實現,大多數裝飾者模式實際上都是半透明的裝飾者模式。