代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。
简单来说,现在比如有一个对象A, 有一个对象B, 本来是对象B直接可以调用对象A实现某种功能的,但是由于特殊的原因对象B无法直接调用对象A来完成功能,而是通过对象C将对象A的调用封装后暴露接口给对象B调用才能完成我们想要的功能,这时我们就可以说对象C是对象A的代理对象。
静态代理在编码时期将代理类写死,然后将由用户自己创建代理类的实例进行使用。
例如如下设计:
其中ChinesePerson的代理类Translators只能在编码时期提前定义好,然后供客户端使用。
Person接口
package ProxyPattern.staticProxy;
public interface Person {
public void sayHello();
public void howAreYou();
}
ChinesePerson类
package ProxyPattern.staticProxy;
public class ChinesePerson implements Person{
public void sayHello(){
System.out.println("哈喽啊!!");
}
public void howAreYou(){
System.out.println("你吃饭了嘛?");
}
}
现在我们想通过调用ChinesePerson获得相应的英文翻译,这时,我们就可以通过代理的方式完成:
我们可以新建一个代理类:
Translators类
package ProxyPattern.staticProxy;
/**
* 英文翻译者类
*/
public class Translators implements Person{
Person ChinesePerson = new ChinesePerson();
public void sayHello(){
ChinesePerson.sayHello();
System.out.println("哈喽啊 : Hello!!");
}
public void howAreYou(){
ChinesePerson.howAreYou();
System.out.println("你吃了吗 :how are you");
}
}
然后只需要执行下面的代码就能获得想要的效果:
package ProxyPattern.staticProxy;
public class StaticTest {
public static void main(String[] args) {
Person person = new Translators();
person.howAreYou();
person.sayHello();
}
}
这便是静态代理,静态代理是以死代码的方式完成代理功能的,优点是实现简单,缺点是灵活性差。
代码地址如下:
设计模式/src/main/java/ProxyPattern/staticProxy/StaticTest.java · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)
而动态代理便解决了静态代理的缺点,能让我们在系统运行时期动态的生成代理类供我们使用,但是动态代理的一个缺点是: 理解和实现起来比较复杂。
好在JDK本身实现了动态代理的实现,我们只需学习它如何使用即可。动态代理可以在程序运行期间创建代理类来让我们使用(只要我们遵守其规则进行编程即可)
同样是和静态代理一样的例子,我们用动态代理的方式进行实现。
它的原理是: 首先我们认为的编写一个ProxyHandler实现指定接口InvocationHandler,然后使用Proxy类的newProxyInstance方法将ProxyHandler和指定需要被代理的类进行自动生成,生成一个我们需要的代理类并创建代理类的实例返回指定接口引用,然后我们就可以使用代理类了。
代码地址如下:
设计模式/src/main/java/ProxyPattern/dynamicProxy/DynamicTest.java · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)
同样,除了JDK的代理支持,还有一些代理框架,比如Cglib,想要了解到请看我的这一个博客:
3.如何实现AOP?(静态代理,Jdk动态代理,cglib动态代理,自定义动态代理)_程序员小牧之的博客-CSDN博客_aop是如何实现的
前面我们所学习的都是在一个系统里的本地代理,那么在实际开发中,我们可能并不想要进行本地代理,我们有时候需要远程代理调用,那么如何进行远程调用代理呢? 这个是个问题。
代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。
好在JDK也为我们提供了一个技术:RMI技术,远程方法调用,该技术能让我们像调用本地方法一样调用远程系统中的方法。
RMI详细学习,请看下面博客:
[RMI远程服务制作]
在上一节,我们用状态模式帮糖果机老板设计了一个厉害的系统之后,糖果机的老板还希望能通过远程的方式实时查询糖果的属性,比如看糖果机中的库存。
这时,远程代理的作用就显示了哈哈哈。员工A接到这个需求后,立马将设计做了出来:
代码地址如下:
设计模式/src/main/java/ProxyPattern/third · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)
运行效果如下:
服务端:
客户端:
代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。