代理模式
什么是代理模式
设计模式中,代理模式是我们经常说到的,也是我们经常使用。
**代理模式:为一个对象(目标类、被代理对象)提供一个替身(代理类、代理对象),用来控制目标对象的访问控制,被代理的对象可以是远程的对象、创建开销大的对象、需要安全控制的对象。**现实中常见的代理模式:租房/买房中介、明星的经纪人等。
为什么要用代理模式
-
中介隔离作用:在某些情况下,使用者不想或者不能直接引用一个目标对象,而代理对象可以在使用者和目标对象之间起到中介的作用,其特征是代理类和被代理类实现相同的接口,这样只需要通过代理对象就能访问到目标对象。
-
开闭原则,增加功能:代理类除了是使用者和被代理类的中介之外,我们还可以通过给代理对象增加额外的功能来扩展目标对象的功能,这样做我们只需要修改代理对象而不需要再修改目标对象,符合代码设计的开闭原则。常见的有:a. 访问权限控制。b. 统一日志输出。
代理对象并没有实现相关的业务能力,实际的业务能力还是交给目标对象,但是代理对象可以在业务能力执行前或者执行后进行一些操作,提供一些特定的服务。例如:我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要修改原来的目标对象,保证了开闭原则。
常见的代理模式实现有两种:1 静态代理。2 动态代理。其中动态代理又分为jdk动态代理和。
静态代理
//歌手接口:目标对象和代理对象的父类
public interface Singer {
/**唱歌*/
void sing(String name);
}
/**歌手刀郎,目标对象,只有刀郎会唱:2020年的第一场雪
*/
public class DaoLang implements Singer{
@Override
public void sing(String name) {
System.out.println("大家好,我是:刀郎......");
System.out.println("开始演唱:2020年的第一场雪");
System.out.println("结束演唱:2020年的第一场雪");
}
public String myHat(){
return "鸭舌帽";
}
}
/**刀郎的经纪人
开演唱会之前,需要收到邀约,开完要收钱。
*/
public class DaoLangAgent implements Singer {
private DaoLang daoLang;
@Override
public void sing(String name){
System.out.println("收到演出邀约");
System.out.println();
System.out.println();
daoLang.sing(name);
System.out.println();
System.out.println();
System.out.println("收到尾款");
}
public DaoLangAgent(DaoLang daoLang){
this.daoLang = daoLang;
}
}
//测试类
public class StatisticProxyTest {
public static void main(String[] args) {
//刀郎作为入参,传入代理对象中
Singer singer = new DaoLangAgent(new DaoLang());
singer.sing("2002年的第一场雪");
}
}
输出结果:
收到演出邀约
大家好,我是:刀郎......
开始演唱:2020年的第一场雪
结束演唱:2020年的第一场雪
收到尾款
上述就是静态代理,我们知道DaoLangAgent就是歌手刀郎的经纪人,想找刀郎唱歌就要联系Agent就行,一切的邀约和付款都是跟Agent打交道,约好时间刀郎就来了。
优缺点
-
静态代理的优点:就是代理模式的有点,在符合开闭原则的情况下对目标对象进行功能扩展,把一些非业务的功能进行剥离,通过代理类进行实现,尤其是权限控制、缓存、日志等。
-
静态代理的缺点:
- 需要为每个目标对象(DaoLang)创建一个代理对象(DaoLangAgent)。万一想要代理蔡琴,有需要搞一个CaiQinAgent,尤其是代理的内容一致的情况下(先邀约,后尾款),每多一个歌手就要多一个代理。
- 如果目标对象有变化,代理对象也要跟着变化,例如:Singer添加了签名功能,那么DaoLangAgent也需要变动,因为DaoLangAgent也实现了Singer,因此代理对象也需要添加签名功能,即使DaoLangAgent不想代理签名,也需要提供相关的方法。
根据静态代理的缺点,能否提供一个统一的功能,针对不同的Signer,实现统一的代理?同时能否针对Singer的指定能力进行代理,而不是所有的能力进行代理?