定义
代理模式(Proxy):属于结构型模式,为一个目标对象提供一个代理,通过代理来实现对该目标进行访问,目的是在对象的基础上,增加额外的功能操作。
静态代理
静态代理:目标对象与代理对象一起实现相同的接口或者继承相同的父类。
静态代理有些类似于装饰者模式,装饰者模式将被装饰的对象作为被装饰者的成员变量,静态代理模式将被代理的目标对象作为代理对象的成员变量。
假设有这样一个场景,老师外出培训,通过网络课堂给我们上了一节课。我们直接来看代码即可,非常容易理解
1 | public interface ITeacher { |
动态代理
动态代理:目标对象要实现接口,代理对象不需要实现接口,代理对象的生产利用到JDK的反射机制,会在内存中动态构建代理对象,通过代理对象调用被代理对象的方法,因此也称为JDK代理。
Java中提供了java.lang.reflect.Proxy这样一个类,这个类有一个静态方法Proxy.newProxyInstance(loader, interfaces, h),有三个参数,第一个参数指定目标对象使用的类加载器,第二个参数为目标对象实现的接口类型,第三个参数为事件处理,执行目标对象的方法时,会触发该事件处理,并且把目标对象方法作为参数传入。
第一个参数很好理解,就是目标对象target.getClass().getClassLoader(),第二个参数也很好理解,是目标对象target.getClass().getInterfaces(),第三个参数类似于一个回调,新建一个匿名内部类InvocationHandler,实现invoke()方法,当真正调用目标对象的某个方法时,会将这个方法名和参数传入这个匿名内部类的invoke方法中,在其中添加需要的逻辑即可。
1 | public interface ITeacher { |
类图
特点
小伙伴们看一下代理模式和装饰者模式的类图,只能说一模一样。都是提供一个接口,装饰者模式是装饰对象持有一个接口对象,然后对功能进行扩展。代理模式是代理者持有一个接口对象,对功能进行代理。其本质都是一样的,但是思想上有些差异。
功能的扩展,一般称为装饰。对象难以获取,接口不对外暴露,一般称为代理。
总结
在某些情况下,客户不想或者不能直接引用一个委托对象,而代理对象可以在客户和委托对象之间起到中介作用。可以实现代理和委托的分离,降低了系统的耦合性,而且可以防止任意用户都能调用目标对象,起到保护目标对象的作用。