設計模式(九)裝飾器模式

職責:動態的爲一個對象增長新的功能設計模式

   裝飾器模式是一種用於代替繼承的技術,無需經過繼承增長子類就能擴展對象的新功能。使用對象的關聯關係代替繼承關係,更加靈活,同時避免類型體系的快速膨脹。session


實現細節:app

——Component抽象構件角色:真實對象和裝飾對象有相同的接口。這樣,客戶端對象就可以以與真實對象相同的方式同裝飾對象交互。ide

——ConcreteComponent具體構件角色(真實對象):io流中的FileInputStream、    FileOutputStream性能

——Decorator裝飾角色:持有一個抽象構件的引用。裝飾對象接受全部客戶端的請求,並把這些請求轉發給真實的對象。這樣,就能在真實對象調用先後增長新的功能。測試

——ConcreteDecorator具體裝飾角色:負責給構件對象增長新的責任。this


 開發中的使用場景:spa

  IO中輸入流和輸出流的設計設計

  Swing包中圖形界面構件功能調試

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

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


 

1. 建立一個抽象組件ICar接口,並建立具體構建角色以及各個具體裝飾角色

 1 package com.ztq.decorator;
 2 
 3 /***
 4  * 抽象組件
 5  * @author ZTQ
 6  *
 7  */
 8 public interface ICar {
 9     void move();
10 }
11 
12 //ConcreteComponent 具體構件角色(真實對象)
13 class Car implements ICar{
14 
15     @Override
16     public void move() {
17         System.out.println("陸地上跑!");
18     }
19     
20 }
21 
22 class SuperCar implements ICar{
23     private ICar car;
24     public SuperCar(ICar car){
25         this.car = car;
26     }
27     
28     @Override
29     public void move() {
30         car.move();
31     }
32     
33 }
34 
35 //ConcreteDecorator具體裝飾角色
36 class FlyCar extends SuperCar{
37 
38     public FlyCar(ICar car) {
39         super(car);
40     }
41     
42     public void fly(){
43         System.out.println("天上飛");
44     }
45     
46     @Override
47     public void move() {
48         super.move();
49         fly();
50     }
51 }
52 
53 //ConcreteDecorator具體裝飾角色
54 class WaterCar extends SuperCar{
55 
56     public WaterCar(ICar car) {
57         super(car);
58     }
59     
60     public void swim(){
61         System.out.println("水裏遊");
62     }
63     
64     @Override
65     public void move() {
66         super.move();
67         swim();
68     }
69 }
70 
71 //ConcreteDecorator具體裝飾角色
72 class AICar extends SuperCar{
73 
74     public AICar(ICar car) {
75         super(car);
76     }
77     
78     public void autoMove(){
79         System.out.println("自動跑");
80     }
81     
82     @Override
83     public void move() {
84         super.move();
85         autoMove();
86     }
87 }

 

2. 建立測試類Client

 1 package com.ztq.decorator;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         Car car = new Car();
 6         car.move();
 7         
 8         System.out.println("增長新的功能:飛行");
 9         FlyCar flycar = new FlyCar(car);
10         flycar.move();
11         
12         System.out.println("增長新的功能:水裏遊");
13         WaterCar waterCar = new WaterCar(car);
14         waterCar.move();
15         
16         System.out.println("增長兩個新的功能,飛行,水裏遊");
17         WaterCar waterCar2 = new WaterCar(new FlyCar(car));
18         waterCar2.move();
19     }
20 }

 

結果:

陸地上跑!
增長新的功能:飛行
陸地上跑!
天上飛
增長新的功能:水裏遊
陸地上跑!
水裏遊
增長兩個新的功能,飛行,水裏遊
陸地上跑!
天上飛
水裏遊

 

UML圖:

 


 

總結:

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

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

  優勢:

  • 擴展對象功能,比繼承靈活,不會致使類個數急劇增長
  • 能夠對一個對象進行屢次裝飾,創造出不一樣行爲的組合,獲得功能更增強大的對象
  • 具體構建類和具體裝飾類能夠獨立變化,用戶能夠根據須要本身增長新的具體構件子類和具體裝飾子類

  缺點:

  • 產生不少小對象。大量小對象佔據內存,必定程度上影響性能
  • 裝飾模式易於出錯,調試排查比較麻煩

 

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

兩個模式都是爲了解決過多子類對象問題。但他們的誘因不同。橋接模式是對象自身現有機制沿着多個維度變化,是既有部分不穩定。裝飾模式是爲了增長新的功能。

相關文章
相關標籤/搜索