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

概念:

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

結構:

  裝飾者模式以透明的方式給一個對象附加上更多的責任,換而言之,客戶端並不會以爲對象在裝飾先後有什麼不一樣,裝飾者模式能夠在不使用創造更多子類的狀況下,將對象的功能拓展。ide

結構圖:

角色分析:

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

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

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

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

代碼:

抽象構建角色:

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組件相似

具體示例

有工人接口,咱們定義了鐵匠,如今要對鐵匠進行不一樣的技能強化。component

工人接口:對象

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

鐵匠實現類:blog

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

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

相關文章
相關標籤/搜索