代理模式和裝飾模式有很大的相似性,二者的類圖(幾乎)是一樣的。下麵分別講解代理模式和裝飾模式。 1、代理模式 一般著名的跑步運動員都會有自己的代理人,如果想聯繫該運動員的比賽事宜,可以直接聯繫他的代理人就可以了。類圖如下所示: IRunner介面如下: Runner類如下所示: RunnerAgen ...
代理模式和裝飾模式有很大的相似性,二者的類圖(幾乎)是一樣的。下麵分別講解代理模式和裝飾模式。
1、代理模式
一般著名的跑步運動員都會有自己的代理人,如果想聯繫該運動員的比賽事宜,可以直接聯繫他的代理人就可以了。類圖如下所示:
IRunner介面如下:
public interface IRunner { public void run(); }
Runner類如下所示:
public class Runner implements IRunner { @Override public void run() { System.out.println("運動員在跑步..."); } }
RunnerAgent代理類如下:
public class RunnerAgent implements IRunner { private IRunner runner; public RunnerAgent(IRunner runner) { this.runner = runner; } @Override public void run() { Random rand = new Random(); if (rand.nextBoolean()) { System.out.println("代理人安排運動員跑步..."); runner.run(); } else { System.out.println("代理人有事情,不安排運動員跑步了..."); } } }
測試場景如下:
public class Main { public static void main(String[] args) { IRunner runner = new Runner(); IRunner agent = new RunnerAgent(runner); System.out.println("有人請求代理人讓運動員跑步..."); agent.run(); } }
輸出結果為:
或者
2、裝飾模式
面對代理模式中的場景,使用裝飾模式如何實現呢?裝飾模式是對類功能的加強,比如增強跑步速度,安裝一個動力裝置等。類圖如下所示:
是不是和代理模式的類圖一模一樣,其實是一樣的,但是實現的意圖是一樣的,先看代碼:
public class RunnerAgent implements IRunner { private IRunner runner; public RunnerAgent(IRunner runner) { this.runner = runner; } @Override public void run() { Random rand = new Random(); if (rand.nextBoolean()) { System.out.println("代理人安排運動員跑步..."); runner.run(); } else { System.out.println("代理人有事情,不安排運動員跑步了..."); } } }
測試場景如下:
public class Main { public static void main(String[] args) { IRunner runner = new Runner(); IRunner superRunner = new RunnerWithJet(runner); System.out.println("有人請求加強版運動員跑步..."); superRunner.run(); } }
輸出結果如下:
3、二者的比較
通過上述的例子可以看出,代理模式和裝飾模式非常類似,甚至代碼都類似。二者最主要的區別是:代理模式中,代理類對被代理的對象有控制權,決定其執行或者不執行。而裝飾模式中,裝飾類對代理對象沒有控制權,只能為其增加一層裝飾,以加強被裝飾對象的功能,僅此而已。
代理模式使用到極致開發就是AOP, 這是各位採用Spring架構開發必然要使用到的技術(Spring學習之第一個AOP程式),它就是使用了代理和反射的技術。代理模式在Java的開發中俯拾皆是, 是大家非常熟悉的模式, 應用非常廣泛, 而裝飾模式是一個比較拘謹的模式, 在實際應用中接觸比較少, 但是也有不少框架項目使用了裝飾模式, 例如在JDK的java.io.*包中就大量使用裝飾模式, 類似如下的代碼:
OutputStream out = new DataOutputStream( new FileOutputStream( "test.txt") )
這是裝飾模式的一個典型應用, 使用DataOutputStream封裝了一個FileOutputStream, 以方便進行輸出流處理。
參考資料:
1、《設計模式之禪》機構類模式大PK章節