設計模式之裝飾模式

裝飾模式

      裝飾模式又名包裝模式。

       裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案。

       裝飾模式以對客戶透明的方式動態的給一個對象附加上更多的責任。換言之,客戶端並不會覺得對象在裝飾前和裝飾後有什麼不同。

       裝飾模式可以在不創造更多子類的情況下,將對象的功能加以擴展。

       裝飾模式把客戶端的調用委派到被裝飾類。裝飾模式的關鍵在於這種擴展完全是透明的。

       裝飾模式使在不必改變原類文件和使用繼承的情況下,動態的擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。


裝飾模式的角色:

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

  ——具體構件角色(Concrete Component):定義一個將要接收附加責任的類。

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

  ——具體裝飾角色(Concrete Decorator):負責給構件對象“貼上”附加的責任。


裝飾模式的特點:

   ——裝飾對象和真實對象有相同的接口。這樣客戶端對象就可以以和真實對象相同的方式和裝飾對象交互。

   ——裝飾對象包含一個真實對象的引用(reference)

  ——裝飾對象接收所有來自客戶端的請求。它把這些請求轉發給真實的對象。

   ——裝飾對象可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。


裝飾模式與繼承的比較

——裝飾模式

          用來擴展特定對象的功能

          不需要子類

          動態

          運行時分配職責

          防止由於子類而導致的複雜和混亂

         更多的靈活性

          對於一個給定的對象,同時可能有不同的裝飾對象,客戶端可以通過它的需要選擇合適的裝飾對象發送消息。

——繼承

          用來擴展一類對象的功能

          需要子類

          靜態

          編譯時分派職責

          導致很多子類產生

          缺乏靈活性


裝飾模式的舉例說明


抽象構件角色Component

  

//抽象構件角色
public interface Component {
    public void doSomething();
}

具體構件角色ConcreteComponent   要實現抽象構件接口

//具體構件角色
public class ConcreteComponent implements Component {
    @Override
    public void doSomething() {
        System.out.println("功能A");
    }
}

裝飾角色(Decorator) 持有一個構件(Component)對象的引用,並定義一個與抽象構件接口一致的接口

//裝飾角色
public class Decorator implements Component {

    private Component component;

    public Decorator(Component component)
    {
        this.component=component;
    }
    @Override
    public void doSomething() {
        component.doSomething();
    }
}


具體裝飾角色(Concrete Decorator):負責給構件對象“貼上”附加的責任。


//具體裝飾角色
public class ConcreteDecorator1 extends Decorator {
    public ConcreteDecorator1(Component component) {
        super(component);
    }

    @Override
    public void doSomething() {
        super.doSomething();    //To change body of overridden methods use File | Settings | File Templates.
        this.doAnotherSomething();
    }

    private void doAnotherSomething()
    {
        System.out.println("功能B");
    }
}

//具體裝飾角色
public class ConcreteDecorator2 extends Decorator {
    public ConcreteDecorator2(Component component) {
        super(component);
    }

    @Override
    public void doSomething() {
        super.doSomething();    //To change body of overridden methods use File | Settings | File Templates.
        this.doAnotherSomething();
    }

    private void doAnotherSomething()
    {
        System.out.println("功能C");
    }
}

測試類Client


public class Client {

    public static void main(String[] args)
    {
        /*


        //類比於節點流
        Component component = new ConcreteComponent();

        // 類比於過濾流
        Component component2 = new ConcreteDecorator1(component);

        //類比於過濾流
        Component component3 = new ConcreteDecorator2(component2);

        component3.doSomething();
        */

        Component component = new ConcreteDecorator2(new ConcreteDecorator1(new ConcreteComponent()));
        component.doSomething();


    }
}


         






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章