裝飾器模式

什麼是裝飾器模式

  裝飾器模式又稱包裝(Wrapper)模式,可以實現動態的爲對象添加功能。是繼承關係的一個替代方案,由於能夠在不創造子類的狀況下將對象的功能加以擴展。html

  一般給對象添加新功能,要麼直接修改對象添加,要麼派生對應的子類添加或者使用對象組合的方式。在面上對象的設計中,咱們應該儘可能使用對象組合而不是對象繼承來擴展。裝飾器模式就是基於對象組合的方式,能夠很靈活的給對象添加所須要的功能。java

裝飾器模式的結構和說明

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

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

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

  -具體裝飾角色(Concrete Decorator):負責給構件對象「貼上」附加的責任測試

                              

裝飾器模式的特色

  -裝飾器對象和真是對象有相同的接口。這樣客戶端對象就能夠和真實對象相同的方式和裝飾對象交互。this

  -裝飾對象包含一個真實對象的引用。spa

  -裝飾對象接收全部來自客戶端的請求。它把這些請求轉發給真實的對象。.net

  裝飾對象能夠在轉發這些請求之前或之後增長一些附加功能。這樣就確保了在運行時,不能修改給定對象的構件就能夠在外部增長附加功能。在面向對象的設計中,一般是經過集成來實現對給定類的功能擴展設計

 

示例:

  步驟:

  1. 寫一個組件對象接口 Component.java
  2. 寫一個類 ConcreteComponent.java 實現 組件對象接口
  3. 寫一個裝飾器抽象類 Decorator.java 實現組件接口
  4. 寫裝飾器具體的實現對象 ConcreteDecorator1.java和ConcreteDecorator2.java

步驟一:寫一個組件對象接口

package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 組件對象接口,能夠給這些對象動態的添加職責
 */
public interface Component {
    public void doSomething();
}

步驟二:寫一個具體構件角色

package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 具體的組件對象,實現了組件接口。該對象一般就是被裝飾器裝飾的原始對象,能夠給這個對象添加職責
 */
public class ConcreteComponent implements Component {
    @Override
    public void doSomething() {
        System.out.println("功能A");
    }
}

 

步驟三:寫一個裝飾器抽象類

package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 全部裝飾器的父類,須要定義一個與組件接口一致的接口(主要是爲了實現裝飾器功能的複用,
 *                 即具體的裝飾器A能夠裝飾另一個具體的裝飾器B,由於裝飾器類也是一個Component),並持有一個Component對象,
 *                 該對象其實就是被裝飾的對象。若是不實現組件接口類,則只能爲某個組件添加單一的功能,
 *                 即裝飾器對象不能再裝飾其餘的裝飾器對象
 */
public abstract class Decorator implements Component {
    /**
     * 持有組件對象
     */
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void doSomething() {
        //轉發請求給組件對象,能夠在轉發先後執行一些附加動做
        component.doSomething();
    }
}

 

步驟四:寫裝飾器具體的實現對象

package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 具體的裝飾器類,實現具體要向被裝飾對象添加的功能。用來裝飾具體的組件對象或者另一個具體的裝飾器對象
 */
public class ConcreteDecorator1 extends Decorator {
    public ConcreteDecorator1(Component component) {
        super(component);
    }

    @Override
    public void doSomething() {
        super.doSomething();
        this.doAnotherThing();
    }

    /**
     * 新功能
     */
    private void doAnotherThing() {
        System.out.println("功能B");
    }
}
package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 具體的裝飾器類,實現具體要向被裝飾對象添加的功能。用來裝飾具體的組件對象或者另一個具體的裝飾器對象
 */
public class ConcreteDecorator2 extends Decorator{
    public ConcreteDecorator2(Component component) {
        super(component);
    }

    @Override
    public void doSomething() {
        super.doSomething();
        this.doAnotherThing();
    }

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

 

步驟五:測試

package org.burning.sport.design.pattern.decoratorpattern;

/**
 *  @Description: 裝飾器模式(包裝模式Wrapper)
 *   裝飾模式可以實現動態的爲對象添加功能,是從一個對象外部來給對象添加功能。
 *   裝飾器模式的本質就是動態組合,動態是手段,組合纔是目的
 */
public class ClientMain {
    public static void main(String[] args) {
        //節點流
//        Component component = new ConcreteComponent();  //首先建立須要被裝飾的原始對象(即要被裝飾的對象)
        //過濾流
//        Component component2 = new ConcreteDecorator1(component); //給對象透明的增長功能B並調用
        //過濾流
//        Component component3 = new ConcreteDecorator2(component2);//給對象透明的增長功能C並調用
//        component3.doSomething();

        Component component1 = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent()));

        component1.doSomething();

    }
}

 

 

https://gitee.com/play-happy/base-project

參考:

[1] 博客, http://blog.csdn.net/hust_is_lcd/article/details/7884320

[2] 博客,http://www.runoob.com/design-pattern/decorator-pattern.html

相關文章
相關標籤/搜索