裝飾器模式又稱包裝(Wrapper)模式,可以實現動態的爲對象添加功能。是繼承關係的一個替代方案,由於能夠在不創造子類的狀況下將對象的功能加以擴展。html
一般給對象添加新功能,要麼直接修改對象添加,要麼派生對應的子類添加或者使用對象組合的方式。在面上對象的設計中,咱們應該儘可能使用對象組合而不是對象繼承來擴展。裝飾器模式就是基於對象組合的方式,能夠很靈活的給對象添加所須要的功能。java
-抽象構件角色(Component):給出一個抽象接口,以規範準備接收附加責任對象。git
-具體構件角色(Concrete Component):定義一個將要接收附加責任的類。app
-裝飾角色(Decorator):持有一個構件(Component)對象引用,並定義一個與抽象構件接口一致的接口ide
-具體裝飾角色(Concrete Decorator):負責給構件對象「貼上」附加的責任測試
-裝飾器對象和真是對象有相同的接口。這樣客戶端對象就能夠和真實對象相同的方式和裝飾對象交互。this
-裝飾對象包含一個真實對象的引用。spa
-裝飾對象接收全部來自客戶端的請求。它把這些請求轉發給真實的對象。.net
裝飾對象能夠在轉發這些請求之前或之後增長一些附加功能。這樣就確保了在運行時,不能修改給定對象的構件就能夠在外部增長附加功能。在面向對象的設計中,一般是經過集成來實現對給定類的功能擴展設計
步驟:
步驟一:寫一個組件對象接口
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(); } }
[1] 博客, http://blog.csdn.net/hust_is_lcd/article/details/7884320
[2] 博客,http://www.runoob.com/design-pattern/decorator-pattern.html