一天一個設計模式:裝飾者模式


概念:

  裝飾者模式又稱為包裝(wrapper)模式。裝飾者模式對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案。

結構:

  裝飾者模式以透明的方式給一個對象附加上更多的責任,換而言之,客戶端並不會覺得對象在裝飾前后有什么不同,裝飾者模式可以在不使用創造更多子類的情況下,將對象的功能拓展。

結構圖:

角色分析:

    抽象構件(Component)角色:給出一個抽象接口,以規范准備接受附加責任的對象。

  具體構件(ConCreteComponent)角色:定義一個將要接受附加責任的類。

  裝飾(Decorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件接口一致的接口。

  具體裝飾(ConcreteDecorator)角色:負責給構件對象“貼上”附加的責任。

代碼:

抽象構建角色:

public interface Component { public void sampleOperation(); }
View Code

具體構件角色:

public class ConcreteComponent implements Component { @Override public void sampleOperation() { // 寫相關的業務代碼
 } }
View Code

裝飾者角色:

public class Decorator implements Component{ private Component component; public Decorator(Component component){ this.component = component; } @Override public void sampleOperation() { // 委派給構件
 component.sampleOperation(); } }
View Code

具體裝飾者角色:

public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void sampleOperation() {      super.sampleOperation(); // 寫相關的業務代碼
 } }
//B組件類似

具體示例

有工人接口,我們定義了鐵匠,現在要對鐵匠進行不同的技能強化。

工人接口:

public interface Worker { void working(); }
View Code

鐵匠實現類:

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("我是一個鐵匠"); } }
View Code

技能實現類:

public class Skill implements Worker {
    private Worker worker;

    public Skill(Worker worker) {
        this.worker = worker;
    }

    @Override
    public void working() {
        worker.working();
    }

    //為半透明模式做的拓展
    public void heating(){}
}
View Code

具體的技能類1:

public class Hardening extends Skill { public Hardening(Worker worker) { super(worker); } @Override public void working() { System.out.println("我在淬火"); } }
View Code

具體的技能類2:

public class Beat extends Skill { public Beat(Worker worker) { super(worker); } @Override public void working() { System.out.println("我在反復地捶打"); } }
View Code

 

補充:

裝飾者模式的簡化

1.去掉接口的形式,直接繼承自要被裝飾的類即可。

2.直接使用實現接口的形式實現裝飾,而不用再額外加一層繼承關系。適用於只有一個強化關系的情況

 

透明度的要求:

  裝飾者模式要求程序不應該聲明需要被裝飾的實體類,而是應該聲明抽象接口。

用示例中的聲明表示就是下面這樣:

即所有的人,都是工人,鐵匠是工人,會淬火的鐵匠也是工人。

        Worker worker1 = new Smith("李鐵蛋",18);
        Worker worker2 = new Hardening(worker1);
View Code

半透明的裝飾模式:

  當發現工人接口並不能滿足所有的要求的時候,要想實現透明度要求,必須在接口中添加新方法,所以很多實現的裝飾者模式都是采取“半透明”的方式,即裝飾者類可以對接口進行拓展,同時聲明的時候,可以選擇以裝飾者類為准。

  本例中,裝飾者類就是技能類,我們為淬火技能類添加加熱方法

        Worker worker = new Smith("李狗蛋",18);
        Hardening smith = new Hardening(worker);
        smith.heating();
View Code

  半透明的裝飾者模式是介於裝飾者模式跟適配器模式中的,適配器模式的思路是改變接口,也可以通過改寫或新增方法實現,大多數裝飾者模式實際上都是半透明的裝飾者模式。

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM