設計模式之(十)裝飾模式(DECORATOR)

  在購買了一個房子後,若是是毛坯房,確定不合適直接入住的。須要對它進行裝修:地面找平貼地磚、批牆貼牆紙、吊頂裝訂以及買須要的傢俱,住進去之後也可能根據須要再添加或者去掉一些傢俱或者修改一些東西。因此的這一切,都是爲了住起來舒服,也就是更好試用這個房子。這個裝修過程,基本上就是裝飾模式須要作的事情。ide

  引伸到軟件方面,一個原有的功能,可能須要添加一些輔助功能才能更好的應用。爲了更好的、更加靈活的處理這樣的須要,根據平常針對此類功能很好的設計寫法進行了抽象。看起來就是對原來的功能進行了一些包裝同樣。搞明白裝飾模式要解決的問題場景後。咱們先來看下這個模式的定義:this

動態的給動向添加一些額外的職責,就添加功能來講,裝飾模式比生成子類更加靈活。spa

  類圖和組成元素

                                                

 (抽象組件類)Component:定義一個對象接口,能夠給這個對象動態的添加職責;設計

 (具體組件類)ConreteComonent:定義一個對象,能夠給這個對象添加職責。被裝飾的原始類代理

 (抽象裝飾着)Derocater:定義一個接口,而且繼承 Component,並且擁有一個 Component 類型的屬性。code

 (具體裝飾着)ConcreteDerocater:是具體的裝飾着,也能夠做爲被裝飾者來裝飾。對象

示例

   爲了更好的展現裝飾模式的。這裏舉個例子加深理解。給一個警察添加裝備來舉例。通常都配置警棍,可是根據每次執行任務的不一樣,來配置相應的裝備,看例子blog

//警察  至關於 Component
public interface Jingcha {
    public  void addZhuangb();
}

//特警 至關於 ConcreteComponent 
public class TeJing implements Jingcha {

    @Override
    public void addZhuangb() {
        // TODO Auto-generated method stub
        System.out.println("警棍");
    }
}

//特警 至關於 ConcreteComponent 被裝飾的原始類
public class TeJing implements Jingcha {

    @Override
    public void addZhuangb() {
        // TODO Auto-generated method stub
        System.out.println("警棍");
    }
}

//裝飾警察 至關於 Decorate,抽象的裝飾器類
public abstract class DecorateJingcha implements Jingcha {

    Jingcha jc = null;
    public DecorateJingcha(Jingcha jc){
        this.jc = jc;
    }
    
    @Override
    public abstract void addZhuangb();
}

//裝飾類之一
public class DecorateJingchaFDY extends DecorateJingcha {

    public DecorateJingchaFDY(Jingcha jc) {
        super(jc);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void addZhuangb() {
        // TODO Auto-generated method stub
        jc.addZhuangb();
        System.out.println("防彈衣");
    }

}

//裝飾類之一
public class DecorateJingchaSQ extends DecorateJingcha {

    public DecorateJingchaSQ(Jingcha jc) {
        super(jc);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void addZhuangb() {
        // TODO Auto-generated method stub
        jc.addZhuangb();
        System.out.println("手槍");
    }
    
}

//裝飾類之一
public class DecorateJingchaYSY extends DecorateJingcha {

    public DecorateJingchaYSY(Jingcha jc) {
        super(jc);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void addZhuangb() {
        // TODO Auto-generated method stub
        jc.addZhuangb();
        System.out.println("夜視儀");
    }
}
 1 public class Client {
 2     public static void main(String[] args) {
 3         Jingcha jc = new TeJing();
 4         //維護抗議遊行秩序,只用警棍就能夠
 5         System.out.println("------維護抗議遊行秩序,只用警棍就能夠-------");
 6         jc.addZhuangb();
 7         //晚上維護抗議遊行秩序
 8         System.out.println("------晚上維護抗議遊行秩序,需另外加上夜視儀-------");
 9         DecorateJingcha yesy = new DecorateJingchaYSY(jc);
10         yesy.addZhuangb();
11         //處理恐怖襲擊事件
12         System.out.println("------處理晚上恐怖襲擊事件,要槍、防彈衣-------");
13         DecorateJingcha dch1 = new DecorateJingchaSQ(jc);
14         DecorateJingcha dch2 = new DecorateJingchaFDY(dch1);
15         dch2.addZhuangb();
16     }
17 }
18 
19 -----------------------------執行效果------------------------------------
20 ------維護抗議遊行秩序,只用警棍就能夠-------
21 警棍
22 ------晚上維護抗議遊行秩序,需另外加上夜視儀-------
23 警棍
24 夜視儀
25 ------處理晚上恐怖襲擊事件,要槍、防彈衣-------
26 警棍
27 手槍
28 防彈衣

  經過例子看出來,裝飾器模式能夠很靈活的實現須要的功能。並且符合開閉原則。繼承

分析此模式

   首先分析一下實現方面須要注意什麼呢:接口

     1、裝飾器類和被裝飾器都是實現共同的接口,這樣有個好處是裝飾類也能做爲被裝飾類來進一步裝飾。

             2、裝飾器類和被裝飾類除了要實現共同的接口外,裝飾器類還應該有共同的接口。這裏主要是引入被裝飾的類所謂屬性

             3、根據定義能夠看出來,此模式比繼承靈活。這主要體如今試用的是類的組合方式來調用。和繼承比起來不用所有繼承過來。

             四,裝飾器一次儘可能少實現功能。這樣在調用的時候組合起來更加靈活。

        這個模式的有點是什麼呢.? 比繼承更加靈活;更加容易複用功能;簡單繼承關係,簡化搞定類的定義。原始類雖然被裝飾了,可是它自己並無被該表,只是在類的外部進行修改。也有點相似給原始類加上了一些外殼。

  每一個模式的出現都有必定的目的,這個模式的目的是什麼?就是根據業務靈活組合對象,複用已有類實現功能須要。也能夠理解爲把有些複雜的功能簡單化,分散化,運行時根據須要來組合使用。

        代理模式和這個模式在實現上很是的類似,這個在寫代理模式的時候再詳細分析下。裝飾模式就寫到這裏了

相關文章
相關標籤/搜索