设计模式笔记之十二 (代理模式)
代理模式
代理模式是为一个真实对象提供一个代理对象来控制真实对象的访问。真实对象和代理对象通常具有相同的外部接口。
最近我们实验室的老总们带着秘书去<海<天|盛>宴>参加聚会了,但是实验室却离不开他们,所以他们留下了电话,于是当遇到事情的时候还是能汇报给远程的老总们知道:
class LaoZong { public void report(String reporter, String content) { System.out.println("报告者: " + reporter + ", 内容: " + content); } } public class Proxy { public static void main(String[] args) { LaoZong lz = new LaoZong(); lz.report("员工-张三", "求加工资"); lz.report("员工-李四", "求加工资"); lz.report("员工-王五", "求加工资"); lz.report("员工-赵六", "求加工资"); lz.report("员工-马七", "求加工资"); lz.report("顾问-林阿标", "实验室员工人心浮动,求破!"); lz.report("厂长-加藤音", "兽人工厂内部出现了问题,求破!"); lz.report("部长-财正", "实验室资金链出问题了,求Money"); lz.report("部长-刘玉疯", "今晚老公不在家"); } }
老总们一下子就愤怒了,你们这么频繁的访问我,我怎么受得了,我还怎么在<海<天|盛>宴>中学习先进(此处不断句,一个字以后断句,我怕你们想差了)性经验啊!
顾问林阿标向老总们提出了一个新的解决方案:要不我给你们当个代理老总,有什么事情先报告给我,我再传达给你们,当然有些小事情老总们就不需要关心了。老总一听,觉得可以啊,所以把林阿标顾问提成管理层了:
interface Manager { public void report(String reporter, String content); } class LaoZong implements Manager { public void report(String reporter, String content) { System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 待定, 处理者: 老总"); System.out.println(); } } class LaoZongProxy implements Manager { Manager manager; public void report(String reporter, String content) { if (reporter.startsWith("员工")) { System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 不同意, 处理者: 老总代理林阿标"); System.out.println(); } else if (reporter.endsWith("刘玉疯")){ System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 老总没空, 我有空去. 处理者: 老总代理林阿标"); System.out.println(); } else { if (manager == null) { manager = new LaoZong(); } manager.report(reporter, content); } } } public class Proxy { public static void main(String[] args) { Manager lzProxy = new LaoZongProxy(); lzProxy.report("员工-张三", "求加工资"); lzProxy.report("员工-李四", "求加工资"); lzProxy.report("员工-王五", "求加工资"); lzProxy.report("员工-赵六", "求加工资"); lzProxy.report("员工-马七", "求加工资"); lzProxy.report("顾问-林阿标", "实验室员工人心浮动,求破!"); lzProxy.report("厂长-加藤音", "兽人工厂内部出现了问题,求破!"); lzProxy.report("部长-彩正", "实验室资金链出问题了,求Money"); lzProxy.report("部长-刘玉疯", "今晚老公不在家"); } }
以上就是一个简单的代理的例子,“林阿标”负责代理“老总”,来对访问进行控制,并且将耗时的打电话于远程的老总沟通的活计封装了起来。
当然如果老总要负责的事情不止report一个的话,我们可以用动态代理的方式来处理:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; interface Manager { public void report(String reporter, String content); public void paiMaPi(String paier, String content); } class LaoZong implements Manager { public void report(String reporter, String content) { System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 待定, 处理者: 老总"); System.out.println(); } public void paiMaPi(String paier, String content) { System.out.println("拍者: " + paier + ", 内容: " + content); System.out.println("答复: 好爽, 处理者: 老总"); System.out.println(); } } class LaoZongProxy implements InvocationHandler { private Object sub; public LaoZongProxy() { } public LaoZongProxy(Object obj) { sub = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String reporter = (String) args[0]; String content = (String) args[1]; if (reporter.startsWith("员工")) { System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 不同意, 处理者: 老总代理林阿标"); System.out.println(); } else if (reporter.endsWith("刘玉疯")) { System.out.println("报告者: " + reporter + ", 内容: " + content); System.out.println("答复: 老总没空, 我有空去. 处理者: 老总代理林阿标"); System.out.println(); } else { method.invoke(sub, args); } return null; } } public class Proxy { public static void main(String[] args) { Manager lz = new LaoZong(); // 这就是被代理的类 InvocationHandler ih = new LaoZongProxy(lz); //代理生成器 Class<? extends Manager> cls = lz.getClass(); //动态代理 Manager lzProxy = (Manager) java.lang.reflect.Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ih); lzProxy.report("员工-张三", "求加工资"); lzProxy.report("员工-李四", "求加工资"); lzProxy.report("员工-王五", "求加工资"); lzProxy.report("员工-赵六", "求加工资"); lzProxy.report("员工-马七", "求加工资"); lzProxy.report("顾问-林阿标", "实验室员工人心浮动,求破!"); lzProxy.report("厂长-加藤音", "兽人工厂内部出现了问题,求破!"); lzProxy.report("部长-彩正", "实验室资金链出问题了,求Money"); lzProxy.report("部长-刘玉疯", "今晚老公不在家"); lzProxy.paiMaPi("厂长-加藤音","老总你最棒"); lzProxy.paiMaPi("部长-彩正","老总你好棒"); lzProxy.paiMaPi("女秘书","老总你好强"); } }
至此,终于将结构型模式的坑填满了,下面就是慢慢填行为型模式的坑。