代理模式和裝飾模式區別

代理模式 vs 裝飾模式

  代理模式和裝飾模式有很大的相似性,二者的類圖(幾乎)是一樣的。下面分別講解代理模式和裝飾模式。

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 RunnerWithJet implements IRunner {
    private IRunner runner;

    public RunnerWithJet(IRunner runner) {
        this.runner = runner;
    }

    @Override
    public void run() {
        System.out.println("給運動員屁股後加一個推進裝置...");
        runner.run();
    }
}
複製代碼

測試場景如下:

複製代碼
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, 以方便進行輸出流處理。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章