一、前言:
设计模式,是一个好套路。Java 中有23种,都是靠前人一步一步总结出来的好东西。本项目的源码 GitHub 。
二、代理模式
我在这里给大家简单的讲一下,用我在参加软件设计师资格证培训 课程中所学的例子。就是 司机开车出现交通事故,然后司机是不可能直接去和伤者(擦破了点皮) 进行直接对接的,因为怕被打。所有他会去找一个律师,让律师代表他去处理相关的事故问题。那么律师的职能就相当于代理。在代码中怎么体现?下面我们来看具体例子。
1.定义接口
在交通法律当中,处理交通事故的流程,那么就是一个接口。不管是司机、律师还是的赔偿都要按照法律程序来。那么我们就挑重点,选取 谈判 和 赔偿 定义接口。
package com.proxy.iservice; /** * 法律法规 * @author TongZhou * */ public interface ILayRules { /** * 谈判 */ public void negotiation(); /** * 赔偿 */ public void satisfy(); }
2、实现接口的 司机 和 律师
不管是司机自己还是律师代理,都要走法律程序。
司机的实现类:
package com.proxy.service; import com.proxy.iservice.ILayRules; /** * 司机 * @author TongZhou * */ public class Driver implements ILayRules{ /** * 实现法律法规的谈判 */ @Override public void negotiation() { System.out.println(" 我愿意支付1000元的费用,为其治疗。 "); } /** * 司机实现了法理的付款条例 */ @Override public void satisfy() { System.out.println(" 司机支付了1000元!"); } }
都知道律师帮司机处理,当然是司机出钱去请律师,所以律师拥有司机作为成员就可以了。
律师的实现类:
package com.proxy.service; import com.proxy.iservice.ILayRules; /** * 律师也实现了法律规定 * @author TongZhou * */ public class Lawyer implements ILayRules{ // 司机作为律师一个属性 private Driver driver; public Lawyer(Driver driver) { this.driver=driver; } @Override public void negotiation() { System.out.println(" 我的客户的话: "); driver.negotiation(); } @Override public void satisfy() { System.out.println(" 我客户支付了: "); driver.satisfy(); } }
调用方法查看效果。
package com.proxy.face; import com.proxy.service.Driver; import com.proxy.service.Lawyer; public class Main { public static void main(String[] args) { //司机对象 Driver driver=new Driver(); //律师对象 Lawyer lawyer=new Lawyer(driver); // 律师谈判 lawyer.negotiation(); //律师支付 lawyer.satisfy(); } }
效果如下:
那么这个是一个简单代理模式的案例!
三、JDK 动态代理
JDK 的动态代理,也是基于上述的代理模式。如果我们不知道 司机类会做出什么反应,那么我们就通过接口去拿到他的实现方法,不用在去写律师的类了。实现代码如下:
package com.proxy.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.proxy.iservice.ILayRules; /** * 这是 JDK 的动态代理 * * @author TongZhou * */ public class JDKProxy implements InvocationHandler { // 这是被代理的类 private Driver driver; /** * 构造方法 * * @param driver */ public JDKProxy(Driver driver) { this.driver = driver; } /** * 通过接口 拿到被代理类 的具体实现 * * @return 返回一个呗代理的新对象 */ public ILayRules createProxy() { /** * 获取代理对象 * * 这是通过对象的加载 应该了反射机制 * * driver.getClass().getClassLoader() 这是找到需要代理的类 * * driver.getClass().getInterfaces() 这是找到需要代理类继承的接口 * * this 代表的当前的类 也就是 JDKProxy对象 * */ ILayRules proxy = (ILayRules) Proxy.newProxyInstance(driver.getClass().getClassLoader(), driver.getClass().getInterfaces(), this); // 这是通过类的加载 应用到了反射机制 //ILayRules proxy=(ILayRules) Proxy.newProxyInstance(Driver.class.getClassLoader(), Driver.class.getInterfaces(), this); return proxy; } /** * 给被代理类增加代码 * * invoke方法中填写增强代码 调用代理对象的任何方法都会首先调用invoke方法 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("negotiation".equals(method.getName())) { System.out.println("司机的谈判内容是:"); //传入需要加强的对象和参数 Object result = method.invoke(driver, args); return result; } return method.invoke(driver, args); } }
主函数的的测试代码:
package com.proxy.face; import com.proxy.iservice.ILayRules; import com.proxy.service.Driver; import com.proxy.service.JDKProxy; import com.proxy.service.Lawyer; public class Main { public static void main(String[] args) { //司机对象 Driver driver=new Driver(); // //律师对象 // Lawyer lawyer=new Lawyer(driver); // // // 律师谈判 // lawyer.negotiation(); // // //律师支付 // lawyer.satisfy(); //创建代理服务 JDKProxy jdkProxy=new JDKProxy(driver); ILayRules iLayRules=jdkProxy.createProxy(); iLayRules.negotiation(); iLayRules.satisfy(); } }
测试结果:
总结,这就是 JDK 的代理模式。感觉前人的设计 ,真的好牛 X 。 谢谢开发 JDK 的团队!
本项目的源码 GitHub地址