网站的百度推广怎么做的,广告设计公司策划书,兴义网络推广,网站文件结构文章目录什么是代理模式一. 代理模式简介二. 静态代理模式三. 动态代理模式万能模版前言#xff1a;笔记基于狂神设计模式视频、《大话设计模式》观后而写 #xff08;最近一直在更新之前的刷题博客#xff0c;今天久违地更新一篇新博客啦#xff5e;#xff09; 什么是代…
文章目录什么是代理模式一. 代理模式简介二. 静态代理模式三. 动态代理模式万能模版前言笔记基于狂神设计模式视频、《大话设计模式》观后而写 最近一直在更新之前的刷题博客今天久违地更新一篇新博客啦 什么是代理模式
一. 代理模式简介 代理模式是很常用的设计模式噢同时也有很多的类型适当学习一下是非常有必要的 定义为其他对象提供一种代理以控制对这个对象的访问。 可以理解为在访问对象时引入一定程度的间接性由这种间接性来附加多种用途。UML 图代理组合真实角色代理和真实对色都继承公共接口 举个例子经纪人代理、明星真实角色都继承“接戏”接口。想找明星演戏的话就得通过经纪人的“接戏”把明星想象成经纪人的私有化对象。这样做的话经纪人可以在自己的“接戏”方法上添加筛选、谈薪等任务而明星只需关注自己的业务即可。在上面这个例子里代理模式的好处就有体现出来了。真实角色更加地专一并且在代理角色的拓展也遵守了OOP原则的开放封闭原则。代理模式的分类 静态代理动态代理这两种类型下文有结合代码使用、讲解远程代理为一个对象在不同地址空间提供局部代表用于隐藏一个对象存在于不同地址空间的事实比如调用另一台PC的方法虚拟代理用于存放实例化需要很长时间的真实对象可以达到性能的最优化。比如打开哔哩哔哩卡顿情况先显示文字而图片、视频流可能就只是一个白框之类的玩意之后再逐渐加载出来这里就用到了虚拟代理安全代理、智能指引等其他分类感兴趣可以去查查
二. 静态代理模式
角色分类 抽象角色接口 or 抽象类。真实角色就被代理的角色代理角色真实角色的代理一般会加一些附属操作。客户访问代理角色的人。 好处 使真实角色的操作更加纯粹不用关注一些公共的业务。公共业务交给代理角色实现了业务的分工公共业务发生拓展的时候方便管理 缺点一个真实角色对应一个代理角色代码量增大效率变低样例代码房东、中介、客户、租房试着想想对应上面的什么角色吧
// pspublic class 不要介意这里我是把不同文件的代码直接拷过来了。
// 1. 公共接口
public interface Rent {public void rent();
}// 2. 房东真实角色
public class Host implements Rent{Overridepublic void rent() {System.out.println(房东要出租房子);}
}// 3. 中介代理角色
public class MyProxy implements Rent {// 采用组合方式private Host host;MyProxy() {}MyProxy(Host host) {this.host host;}Overridepublic void rent() {// 可以添加一些更多的内容而主体被代理类却不用关心这些事情只需要做好自己的事即可。// 满足开放封闭原则System.out.println(中介带着看房);host.rent();System.out.println(中介签合同);}
}// 4. 客户访问代理角色
public class Client {public static void main(String[] args) {// 只需要找中介即可不用管房东Host host new Host();MyProxy MyProxy new MyProxy(host);MyProxy.rent();}
}三. 动态代理模式 为了解决上面静态代理模式的缺点这里又有了动态代理模式 这一块不太好理解我写得估计也不太详细建议再看一下视频、或者其他博客 原理动态代理基于反射机制实现。和静态代理的区别 静态代理实现接口再通过接口实现类的实例来代理。动态代理通过反射造出一个接口类的实例。 再原理一点就是通过反射先造出一个带构造方法的接口的克隆体再通过这个克隆体的构造方法生成接口实例 使用到的类 Proxy提供用于创建动态代理类和实例的静态方法生成一个InvocationHandler每个代理实例都具有一个关联的调用处理程序调用代理实例的方法时会被指派到其调用处理程序的 invoke 方法上。com.sun.proxy.$Proxy0 由 Proxy::newProxyInstance() 生成的代理类。实现了传入接口的每一个方法以及Object方法。并且统一调用了InvocationHandler 的 invoke() 方法。 好处 静态代理的好处一个动态代理类代理的是一个接口一般就是对应的一类业务。规避了静态代理的缺点在原始类和接口未知时就确定代理类的代理行为。灵活。 样例代码还是房东中介的例子噢
// 继承 InvocationHandler 接口此时 this 就是一个 InvocationHandler
public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent rent;}// 生成代理类public Object getMyProxy() {return Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}// InvocationHandler 对应的方法 invoke用于处理代理实例并且返回结果。被 $Proxy0 的方法调用Overridepublic Object invoke(Object Proxy, Method method, Object[] args) throws Throwable {// Method 也是反射包下的类和反射相关。System.out.println(动态代理来了噢);Object res method.invoke(rent, args);return res;}
}public class Client {public static void main(String[] args) {// 只需要找中介即可不用管房东Host host new Host();ProxyInvocationHandler proxyInvocationHandler new ProxyInvocationHandler();// 放入被代理对象proxyInvocationHandler.setRent(host);Rent proxy (Rent)proxyInvocationHandler.getMyProxy();// 这里的 rent之后会执行 invoke此时参数 Method 就是 rent// “代理对象”执行“接口方法”然后指派到对应的 InvocationHandler 的 invoke 上proxy.rent();}
}整理无注释一个文件不到30行写完整个动态代理例子
public interface Rent {void rent();
}public class RentDynamicProxy implements InvocationHandler {Rent rent;RentDynamicProxy(Rent rent) {this.rent rent;}Object getProxy() {return Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(启用动态代理);return method.invoke(rent, args);}
}public class Host implements Rent{Overridepublic void rent() {System.out.println(房东出租);}public static void main(String[] args) {Host host new Host();RentDynamicProxy rentDynamicProxy new RentDynamicProxy(host);Rent proxy (Rent)rentDynamicProxy.getProxy();proxy.rent();}
}万能模版
任何接口都可以用噢
public class BetterProxyInvocationHandler implements InvocationHandler {// 1. 被代理的接口private Object target;// 设置被代理的接口public void setTarget(Object target) {this.target target;}// 2. 生成得到代理类public Object getProxy() {return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(执行了 method.getName() 方法);Object res method.invoke(target, args);return res;}
}