Java IO 裝飾者模式
裝飾模式(Decorator)
裝飾模式又名包裝(Wrapper)模式。
裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案。
裝飾模式通過創建一個包裝對象,也就是裝飾,來包裹真實的對象。
裝飾模式以對客戶端透明的方式動態地給一個對象附加上更多的責任。換言之,客戶端並不會覺得對象在裝飾前和裝飾后有什么不同。
裝飾模式可以在不創造更多子類的情況下,將對象的功能加以擴展。
裝飾模式把客戶端的調用委派到被裝飾類。裝飾模式的關鍵在於這種擴展是完全透明的。
裝飾模式的角色
抽象構件角色(Component):給出一個抽象接口,以規范准備接收附加責任的對象。
具體構件角色(Concrete Component):定義將要接收附加責任的類。
裝飾角色(Decorator):持有一個構件(Component)對象的引用,並定義一個與抽象構件接口一致的接口。
具體裝飾角色(Concrete Decorator):負責給構件對象“貼上”附加的責任。
Java IO中的裝飾模式
在IO中,具體構件角色是節點流,裝飾角色是過濾流。
FilterInputStream和FilterOutputStream是裝飾角色,而其他派生自它們的類則是具體裝飾角色。
裝飾模式的特點
裝飾對象和真實對象有相同的接口。這樣客戶端對象就可以以和真實對象相同的方式和裝飾對象交互。
裝飾對象包含一個真實對象的引用(reference)。
裝飾對象接收所有來自客戶端的請求,它把這些請求轉發給真實的對象。
裝飾對象可以在轉發這些請求之前或之后附加一些功能。
這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。
程序實例
public interface Component { public void doSomething(); }
這是抽象構件角色,是一個接口。具體構件角色實現這個接口:
public class ConcreteComponent implements Component { @Override public void doSomething() { System.out.println("功能A"); } }
裝飾角色:
public class Decorator implements Component { private Component component; public Decorator(Component component) { this.component = component; } @Override public void doSomething() { component.doSomething(); } }
其中包含了構件角色的引用,方法調用中利用構件角色的方法。
具體裝飾角色(兩個):
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"); } }
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"); } }
使用測試:
public class Client { public static void main(String[] args) { Component component = new ConcreteComponent(); Component component1 = new ConcreteDecorator1(component); component1.doSomething(); System.out.println("-----------"); Component component2 = new ConcreteDecorator2(component1); component2.doSomething(); } }
輸出:
功能A
功能B
-----------
功能A
功能B
功能C
參考資料
聖思園張龍老師Java SE系列視頻教程,第九十三講。
《Head First設計模式》讀書筆記03 裝飾對象:
http://www.cnblogs.com/mengdd/archive/2013/01/03/2843439.html