天天看點

Java裝飾者模式(decorator)

文章目錄

   裝飾者模式(decorator)

       1.實作細節

       2.案例示範

       3.IO流實作細節

       4.實際使用場景

       5.總結

裝飾者模式(decorator)

 裝飾者模式又稱為包裝模式(Wrapper),作用是用來動态的為一個對象增加新的功能。裝飾模式是一種用于代替繼承的技術,無須通過繼承增加子類就能擴充對象的新功能。使用對象的關聯關系代替繼承關系,更加靈活,同時避免類型體系的快速膨脹。

1.實作細節

角色 說明

Component 抽象元件角色:真實對象和裝飾對象有相同的接口,這樣用戶端對象就能夠以與真實對象相同的方式同裝飾對象互動

ConcreteComponent 具體元件角色(真實對象):IO流中的FileInputStream,FileOutputStream

Decorator 裝飾角色:持有一個抽象元件的引用,裝飾對象接受所有用戶端的請求,并把這些請求轉發給真實的對象,這樣就能在真實對象調用前後增加新的功能

ConcreteDecorator 具體裝飾角色:負責給元件對象增加新的責任

Java裝飾者模式(decorator)

2.案例示範

 案例通過汽車來給大家示範:

Java裝飾者模式(decorator)

/**
 * 抽象建構
 * @author Administrator
 *
 */
public interface ICar {
    void move();
}

//ConcreteComponent 具體構件角色(真實對象)
class Car implements ICar {
    @Override
    public void move() {
        System.out.println("陸地上跑!");
    }
}

//Decorator裝飾角色
class SuperCar implements ICar {
    protected ICar car;
    public SuperCar(ICar car) {
        super();
        this.car = car;
    }

    @Override
    public void move() {
        car.move();
    }
}

//ConcreteDecorator具體裝飾角色
class FlyCar extends SuperCar {

    public FlyCar(ICar car) {
        super(car);
    }
    
    public void fly(){
        System.out.println("天上飛!");
    }

    @Override
    public void move() {
        super.move();
        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();
    }
    
}

//ConcreteDecorator具體裝飾角色
class AICar extends SuperCar {
    
    public AICar(ICar car) {
        super(car);
    }
    
    public void autoMove(){
        System.out.println("自動跑!");
    }
    
    @Override
    public void move() {
        super.move();
        autoMove();
    }
}      

測試

public static void main(String[] args) {
    Car car  = new Car();
    car.move();
    
    System.out.println("增加新的功能,飛行----------");
    FlyCar flycar = new FlyCar(car);
    flycar.move();
    
    System.out.println("增加新的功能,水裡遊---------");
    WaterCar  waterCar = new WaterCar(car);
    waterCar.move();
    
    System.out.println("增加兩個新的功能,飛行,水裡遊-------");
    WaterCar waterCar2 = new WaterCar(new FlyCar(car));
    waterCar2.move();
    
    
//      Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(new File("d:/a.txt"))));
    
}      

輸出結果

陸地上跑!
增加新的功能,飛行----------
陸地上跑!
天上飛!
增加新的功能,水裡遊---------
陸地上跑!
水上遊!
增加兩個新的功能,飛行,水裡遊-------
陸地上跑!
天上飛!
水上遊!      

 通過輸出我們能看出在沒事繼承的情況下,我們擴充了對象的功能。

3.IO流實作細節

   Component抽象構件角色:

   • io流中的InputStream、OutputStream、Reader、Writer

   ConcreteComponent具體構件角色:

   • io流中的FileInputStream、FileOutputStream

   Decorator裝飾角色:

   • 持有一個抽象構件的引用:io流中的FilterInputStream、FilterOutputStream

   ConcreteDecorator具體裝飾角色:

   • 負責給構件對象增加新的責任。Io流中的BufferedOutputStream、BufferedInputStream等

4.實際使用場景

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

   Swing包中圖形界面構件功能

   Servlet API 中提供了一個request對象的Decorator設計模式的預設實作類HttpServletRequestWrapper,HttpServletRequestWrapper類,增強了request對象的功能。

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

5.總結

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

   裝飾模式降低系統的耦合度,可以動态的增加或删除對象的職責,并使得需要裝飾的具體建構類和具體裝飾類可以獨立變化,以便增加新的具體建構類和具體裝飾類。

比較 說明

優點 1. 擴充對象功能,比繼承靈活,不會導緻類個數急劇增加

2. 可以對一個對象進行多次裝飾,創造出不同行為的組合,

得到功能更加強大的對象

3. 具體建構類和具體裝飾類可以獨立變化,

使用者可以根據需要自己增加新的具體構件子類和具體裝飾子類。

缺點 1. 産生很多小對象。大量小對象占據記憶體,一定程度上影響性能。

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

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

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