裝飾器模式(Decorator)

1、裝飾模式介紹html

裝飾模式(decorator):表示動態的給一個對象添加一些新的功能(利用子類繼承父類也能夠實現),可是比生成子類方式更靈活。java

也叫裝飾者模式或者裝飾器模式設計模式

例如:咱們每一個人身上穿的衣服,鞋子,領帶,披風均可以理解爲是對人的裝飾session

裝飾器模式類圖:app

Component:定義一個對象接口,能夠給這些對象動態添加職責。真實對象和裝飾者對象有相同的接口,這樣客戶端不用知道內部有裝飾者對象(Decorator)ide

存在的,仍是以以前處理真實對象的相同方式來和裝飾者對象交互。性能

ConcreteComponent:是定義了一個具體的對象(例如:人),也能夠給這個對象添加一些其餘職責。學習

Decorator:裝飾抽象類,繼承了Component,從外類來擴展Component類的功能,但對Component來講,是無需知道Decorator存在的。測試

ConcreteDecorator:就是具體的裝飾對象了(衣服,鞋子..),它起到了給Component添加職責的功能。this

 

2、裝飾模式代碼實現

 定義一個Component對象接口(ICar),汽車移動

1
2
3
4
5
6
/**
  * ICar表示Component:
  */
public  interface  ICar {
     void  move(); //汽車移動
}

定義一個具體真實的對象ConcreteComponent:這裏是Car,就是具體的汽車,未裝飾的汽車

1
2
3
4
5
6
7
//ConcreteComponent:具體的對象
class  Car  implements  ICar{
     @Override
     public  void  move() {
         System.out.println( "汽車移動" );
     }
}

裝飾抽象類Decorator:SuperCar這裏須要持有一個真實對象的引用,也就是Car對象

1
2
3
4
5
6
7
8
9
10
11
12
13
//Decorator:裝飾抽象類
class  SuperCar  implements  ICar{
     protected  ICar car; //持有一個真實對象的引用
     @Override
     public  void  move() {
         car.move(); //這裏調用真實對象的移動方法
     }
     //構造的時候傳參
     public  SuperCar(ICar car) {
         super ();
         this .car = car;
     }
}

開始實現具體的裝飾對象ConcreteDecorator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//ConcreteDecorator:就是具體的裝飾對象
class  FlayCar  extends  SuperCar {
     public  FlayCar(ICar car) {
         super (car);
     }
     //這裏就是新增的功能
     public  void  flay(){
         System.out.println( "---天上飛" );
     }
     @Override
     public  void  move() {
         super .move();
         flay(); //在原有移動的基礎上,裝飾了一個fly的功能
     }
}
//ConcreteDecorator:就是具體的裝飾對象
class  WaterCar  extends  SuperCar {
     public  WaterCar(ICar car) {
         super (car);
     }
     //這裏就是新增的功能
     public  void  swim(){
         System.out.println( "---水裏遊" );
     }
     @Override
     public  void  move() {
         super .move();
         swim(); //在原有移動的基礎上,裝飾了一個swim的功能
     }
}

測試代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
public  static  void  main(String[] args) {
     Car car =  new  Car();
     car.move(); //這裏打印未增長新功能的時候:汽車移動
      
     System.out.println( "--------增長飛行功能-------" );
     FlayCar flyCar =  new  FlayCar(car); //將真實對象傳入裝飾對象中
     flyCar.move(); //這裏就是增長了飛行後的裝飾
      
     System.out.println( "--------增長潛水功能-------" );
     WaterCar waterCar =  new  WaterCar(car); //將真實對象傳入裝飾對象中
     waterCar.move(); //這裏就是增長了潛水功能後的裝飾
      
}

控制檯結果就是:

            汽車移動

            --------增長飛行功能-------

            汽車移動

            ---天上飛

            --------增長潛水功能-------

            汽車移動

            ---水裏遊

整個例子的類圖結構以下:

 

3、總結

裝飾模式(Decorator)也叫包裝器模式(Wrapper)

        裝飾模式下降系統的耦合度,能夠動態的增長或刪除對象的職責,並使得須要裝飾的具體構建類和具體裝飾類能夠獨立變化

以便增長新的具體構建類和具體裝飾類。

優勢:

       擴展功能強,相比繼承來講更靈活。繼承的話會致使子類個數增長。而裝飾者模式不會出現這種狀況。

       能夠對一個對象進行屢次裝飾,創造出不一樣行爲的組合,獲得功能更增強大的對象。

       具體構建類和具體裝飾類能夠獨立變化,用戶能夠根據須要本身增長新的構件子類和具體裝飾類。

缺點:

        產生不少小對象,大量小對象會佔據內存。必定程度上影響了性能。

        裝飾模式易於出錯,調試排查比較麻煩。 

開發中應用的場景:

        IO中輸入流和輸出流

        Swing包中圖形界面構件功能

        Servlet API中提供了一個request對象的Decorator設計模式的默認實現類HttpServletRequestWrapper,加強了request對象的功能。

        Struts2中,request,response,session對象的處理。

裝飾模式和橋接模式的區別:

        兩個模式都是爲了解決過多子類對象的問題,橋接模式是對象自身有過多的維度,形成過多的子類。而讓維度分類後在搭建一個橋樑來聯繫起來。

而裝飾模式是解決在增長新功能的時候產生多個類的問題。

 



Java23種設計模式學習筆記【目錄總貼】

參考資料:

  大話設計模式(帶目錄完整版).pdf

  HEAD_FIRST設計模式(中文版).pdf

  尚學堂_高淇_java300集最全視頻教程_【GOF23設計模式】

相關文章
相關標籤/搜索