一 概述 1.什麼是裝飾者模式? 在不修改類,不使用繼承的前提下,用一個對象來裝飾另一個對象,以擴展目標對象的功能。 2.裝飾者模式的作用: 繼承也可以擴展類的功能,裝飾者模式比繼承更加靈活,因為繼承時子類受父類的約束,比如子類方法不能降低訪問許可權,返回值必須是父類方法返回值的子類,而裝飾模式就不受 ...
一 概述
1.什麼是裝飾者模式?
在不修改類,不使用繼承的前提下,用一個對象來裝飾另一個對象,以擴展目標對象的功能。
2.裝飾者模式的作用:
繼承也可以擴展類的功能,裝飾者模式比繼承更加靈活,因為繼承時子類受父類的約束,比如子類方法不能降低訪問許可權,返回值必須是父類方法返回值的子類,而裝飾模式就不受這些約束,比較靈活。
二 基本裝飾者模式
結構:
- 父類:可以是介面、抽象類、一般類,保證能夠以操作目標對象的方式操作裝飾者,即保證裝飾者擁有與目標對象相同的方法結構。
- 目標類;
- 裝飾者類:其中包含目標對象引用,往往通過構造器註入。
三 高級裝飾者模式
1.不僅可以對目標對象進行多種形式的增強,而且可以構建裝飾者鏈將多種增強形式同時施加到目標對象上。
2.結構
- 父類。
- 目標類:實現或者繼承了父類。
- 裝飾者基類:實現或繼承了父類,只是實現了目標對象方法,並未增強,作為後續增強的基礎。
- 具體裝飾者A類:繼承了裝飾者基類,對目標類進行一種形式的增強。
- 具體裝飾者B類:繼承了裝飾者基類,對目標類進行一種形式的增強。
3.按照功能模塊化原則,一個模塊只負責單一的功能,每一種具體裝飾者類,只負責實現一種增強形式。
4.具體裝飾者類對目標類的增強建立在基類處理結果的基礎上,因此在代碼中通過先super獲取基類的結果,然後再進行增強。
5.構建裝飾者鏈
⑴基本原理:
首先將目標對象傳入一個具體裝飾者對象中,再將該具體裝飾者對象傳入下一個具體裝飾者對象中,以此推進,形成一個裝飾者鏈,對目標對象逐級增強。
⑵構建關鍵:
在具體裝飾者類中通過super獲取基類處理結果,將基類作為中間環節構建裝飾者鏈。
⑶實現Demo
介面
package com.designmode.decorator.senior; public interface ISomeService { String doSome(); }
目標類
package com.designmode.decorator.senior; public class SomeServiceImpl implements ISomeService { @Override public String doSome() { return " abc "; } }
裝飾者基類
package com.designmode.decorator.senior; public class SomeServiceWrapper implements ISomeService { private ISomeService target; public SomeServiceWrapper(ISomeService target) { super(); this.target = target; } @Override public String doSome() { return target.doSome(); } }
具體裝飾者A類
package com.designmode.decorator.senior; public class TrimDecorator extends SomeServiceWrapper { public TrimDecorator(ISomeService target) { super(target); // TODO Auto-generated constructor stub } @Override public String doSome() { // TODO Auto-generated method stub return super.doSome().trim(); } }
具體裝飾者B類
package com.designmode.decorator.senior; public class UpperDecorator extends SomeServiceWrapper { public UpperDecorator(ISomeService target) { super(target); // TODO Auto-generated constructor stub } @Override public String doSome() { // TODO Auto-generated method stub return super.doSome().toUpperCase(); } }
測試類
package com.designmode.decorator.senior; import org.junit.Test; public class DecoratorTest { /** * 裝飾者基類,原樣實現了目標對象的方法,並未增強 */ @Test public void test01() { ISomeService target = new SomeServiceImpl(); ISomeService decorator = new SomeServiceWrapper(target); String result = decorator.doSome(); System.out.println("result=" + result); } /** * 一次增強,對裝飾者基類增強 */ @Test public void test02() { ISomeService target = new SomeServiceImpl(); ISomeService decorator = new TrimDecorator(target); String result = decorator.doSome(); System.out.println("result=" + result); } /** * 形成裝飾者鏈,逐級增強 */ @Test public void test03() { ISomeService target = new SomeServiceImpl(); ISomeService trimDecorator = new TrimDecorator(target);// 一級增強 ISomeService service = new UpperDecorator(trimDecorator);// 二級增強 String result = service.doSome(); System.out.println("result=" + result); } }
三 常見裝飾者應用
IO流中廣泛使用裝飾者模式,一些類正是裝飾了基本輸入輸出流創建的,如XMLWriter\DateOutputStream\BufferedInputstream\
ObjectInputstream等。
四 與靜態代理模式對比
1.相同點:
- 都與目標類實現共同的介面。
- 都可以動態地擴展目標類的功能。
- 都需要在自身類中包含目標對象。
2.不同點
⑴設計目的不同:
- 裝飾者模式是為了增強目標類的功能。
- 靜態代理是為了隱藏與保護目標類。
⑵包含目標對象的方式不同:
- 在裝飾者模式中,目標對象由用戶創建,通過構造器傳入裝飾者中,目標對用戶可見。
- 在靜態代理模式中,目標對象在裝飾者類的無參構造方法中創建,對用戶不可見。
註:靜態代理模式請參考http://www.cnblogs.com/tonghun/p/6925614.html