java 代理模式与装饰模式极其相识,有点定位上的区别
代理模式 vs 装饰模式
https://www.cnblogs.com/luoxn28/p/5535877.html
代理模式和装饰模式有很大的相似性,二者的类图(几乎)是一样的。下面分别讲解代理模式和装饰模式。
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、二者的比较
通过上述的例子可以看出,代理模式和装饰模式非常类似,甚至代码都类似。二者最主要的区别是:代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已。