设计模式之——代理设计模式
来源:互联网 发布:2014网络春晚 白客 编辑:程序博客网 时间:2024/06/03 17:03
代理模式说白了就是中介,A要完成C,并不是直接去完成而是委托中介B去完成,B就是连接A与C的代理,B可以完全替代A去做,有时只需要提供满足C所需要的东西就行。
代理模式分为静态代理(手动实现这些行为的替换) + 动态代理(实现InvocationHandler接口交给虚拟机实现行为的替换)
静态代理
我是一个客户想买一辆车开开,我可以提供买车所有的证件以及买车的行为(具备这些我当然自己就可以去买车了,但是我闲的蛋疼啊,自己去做这些事,毕竟日理万机的工作)
首先呢,我提取了我和中介的共同行为:那就是都可以买车,只是他没有我的相关证件
package com.zndroid.dm.ProxyModel.StaticProxy;/** * Created by luzhenyu on 2017/7/27. */public interface IBuyCar { void buyCar();}
package com.zndroid.dm.ProxyModel.StaticProxy;/** * Created by luzhenyu on 2017/7/27. */public class Client implements IBuyCar { private int money; private String certificate; private String car; public String getCar() { return car; } public void setCar(String car) { this.car = car; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public String getCertificate() { return certificate; } public void setCertificate(String certificate) { this.certificate = certificate; } @Override public void buyCar() { System.out.println("客户 - 签合同"); }}去4儿子店,找到一个中介,他客气滴招待了我,建立了我和他的联系(通过这个联系他能够拿到我的相关信息),他本身也具备买车的行为
package com.zndroid.dm.ProxyModel.StaticProxy;/** * Created by luzhenyu on 2017/7/27. * 相当于中介 * 通常建议使用的是聚合式代理而非继承式代理 * 聚合实现方式中代理类聚合了被代理类,且代理类及被代理类都实现了同一个接口,可实现灵活多变。继承式的实现方式则不够灵活; * 比如,在管理员操作的同时需要进行权限的处理,操作内容的日志记录,操作后数据的变化三个功能。三个功能的排列组合有6种, * 也就是说使用继承要编写6个继承了Admin的代理类,而使用聚合,仅需要针对权限的处理、日志记录和数据变化三个功能编写代理类, * 在业务逻辑中根据具体需求改变代码顺序即可。 */public class Proxy implements IBuyCar { private Client client;//包含客户的引用,这样中介就能给我要相关的证件资料了 public Proxy(Client client) { this.client = client; } @Override public void buyCar() { checkMoney$Certificate(); client.buyCar();//具体实体(客户)动作(也就是最终需要客户签合同操作,代理只起到中介作用,而且客户关心的只是买车,证件检查等操作客户无需关心,交给中介做) shangPai(); client.setCar(jiaoFu()); } private void checkMoney$Certificate() { System.out.println("代理 - 资料核实:" + client.getCertificate() + " and " + client.getMoney());//代理做的东西 } private void shangPai() { System.out.println("代理 - 上牌");//代理做的东西 } private String jiaoFu() { System.out.println("代理 - 交付车辆");//代理做的东西 return "new car"; }}具体使用:
Client mClient = new Client();mClient.setMoney(100);mClient.setCertificate("ID card");Proxy proxy = new Proxy(mClient);proxy.buyCar();log("客户获得了:" + mClient.getCar());log("----------------我是分割线-----------------");
动态代理
基本和静态代理一样,只是要实现InvocationHandler接口,并告诉虚拟机怎么去处理手动插入的过程package com.zndroid.dm.ProxyModel.DynamicProxy;/** * Created by luzhenyu on 2017/7/27. */public interface IBuyCar { void buyCar();}
package com.zndroid.dm.ProxyModel.DynamicProxy;/** * Created by luzhenyu on 2017/7/27. */public class Client implements IBuyCar { private int money; private String certificate; public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public String getCertificate() { return certificate; } public void setCertificate(String certificate) { this.certificate = certificate; } @Override public void buyCar() { System.out.println("客户 - 签合同"); }}
package com.zndroid.dm.ProxyModel.DynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import static java.lang.System.out;/** * Created by luzhenyu on 2017/7/27. * 一般来说,对代理模式而言,一个主题类与一个代理类一一对应,这也是静态代理模式的特点。 * 但是,也存在这样的情况,有n各主题类,但是代理类中的“前处理、后处理”都是一样的,仅调用主题不同。 * 也就是说,多个主题类对应一个代理类,共享“前处理,后处理”功能,动态调用所需主题,大大减小了程序规模,这就是动态代理模式的特点. * * 动态代理是不需要手写代理类的,但是需要实现InvocationHandler接口,在运行时由虚拟机创建代理, * 实际内部原理 参见<a>http://blog.csdn.net/goskalrie/article/details/52458773<a/> */public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object object) { this.target = object; } /** *@param proxy 被代理的对象 *@param method 被代理对象的方法 *@param args 方法的参数 *@return Object 方法返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("buyCar")) { checkMoney$Certificate(); } method.invoke(target, args); if (method.getName().equals("buyCar")) { shangPai(); } return null; } private void checkMoney$Certificate() { String s = "", s1 = ""; try { Method m = target.getClass().getMethod("getMoney", null); s = String.valueOf(m.invoke(target, null)); Method m1 = target.getClass().getMethod("getCertificate", null); s1 = (String)m1.invoke(target, null); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } System.out.println("代理 - 资料核实:" + s + " " + s1);//代理做的东西 } private void shangPai() { System.out.println("代理 - 上牌");//代理做的东西 } public String jiaoFu() { System.out.println("代理 - 交付车辆");//代理做的东西 return "new car"; } public Object getProxy() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }}具体使用:
MyInvocationHandler invocationHandler = new MyInvocationHandler(client);((IBuyCar) (invocationHandler.getProxy())).buyCar();log("客户获得了:" + invocationHandler.jiaoFu());log("----------------我是分割线-----------------");
【欢迎上码】
【微信公众号搜索 h2o2s2】
阅读全文
0 0
- 设计模式之——代理模式
- 设计模式之——代理模式
- 设计模式之——代理模式
- 设计模式之— 代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式之——代理设计模式
- 设计模式之——代理模式(静态代理)
- 设计模式之——代理模式(动态代理)
- 设计模式——代理设计模式
- dcmdata.lib(dcuid.obj) : error LNK2019: 无法解析的外部符号 _GetAdaptersInfo@8,该符号在函数 "struct _IP_ADAPTER_INFO
- ActiveMQ入门
- 求补码的简便算法
- Android Studio 设置文件显示的颜色(在版本管理时会使用,如:git,svn)
- matlab几种括号的用法
- 设计模式之——代理设计模式
- sockaddr和sockaddr_in的区别(转载)
- Android Handler与Looper原理浅析
- poj3279 Fliptile【二进制枚举状态】
- MySQL 运行状态及调优(二)
- 尝试自己写一个工具类实现UGUI的按钮功能
- zabbix3.X配置邮件监控
- http如何像tcp一样实时的收消息?
- Python正则表达式指南