结构型模式--代理模式

视频地址https://www.bilibili.com/video/BV1Ra4y1t7wi/

1.代理模式的定义

定义:代理模式又叫委托模式,是为某各对象提供一个代理对象,并由代理对象控制原对象的引用。通俗的来说代理模式就是生活中常见的中介。

 举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了。

用图表示如下:

 

注意:

一个代理类可以代理多个被委托者或被代理者,因此一个代理类具体代理哪个具体主题角色,是由场景类决定的。最简单的情况是一个主题类和一个代理类。
通常情况下,一个接口只需要一个代理类,具体代理哪个实现类有高层模块决定。

2.代理模式的优点
  • 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
  • 开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

3.代理模式的种类

代理模式有多种不同的实现方式。如果按照代理创建的时期来进行分类:静态代理、动态代理。

静态代理:由程序员创建或特定工具自动生成源代码,再对其进行编译。在程序运行之前,代理类.class文件就已经被创建,代理类和委托类的关系在运行前就确定。

第一步:创建服务类接口

public interface BuyHouse {

void buyHosue();
}

第二步:实现接口服务

public class BuyHouseImpl implements BuyHouse {

@Override
public void buyHosue() {
System.out.println("我要买房");
}
}

第三步:创建代理类

public class BuyHouseProxy implements BuyHouse {

private BuyHouse buyHouse;

public BuyHouseProxy(final BuyHouse buyHouse) {
this.buyHouse = buyHouse;
}

@Override
public void buyHosue() {
System.out.println("买房前准备");
buyHouse.buyHosue();
System.out.println("买房后装修");

}
}

第四步:编写测试类

public class ProxyTest {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
buyHouse.buyHosue();
BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);
buyHouseProxy.buyHosue();
}
}

动态代理:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。真正的代理对象由JDK再运行时为我们动态的来创建。

第一步:编写动态处理器

public class DynamicProxyHandler implements InvocationHandler {

private Object object;

public DynamicProxyHandler(final Object object) {
this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("买房前准备");
Object result = method.invoke(object, args);
System.out.println("买房后装修");
return result;
}
}

第二步:编写测试类

public class DynamicProxyTest {
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
proxyBuyHouse.buyHosue();
}
}

4.代理模式的总结

代理模式使用广泛,尤其是动态代理在大型开发框架中,应用较多并且高效。特别是使用AOP,实现代理模式就更方便了,比如使用Spring AOP和AspectJ这样的工具。
在使用AOP框架时,需要关注几个名词:

  • 切面(Aspect)
  • 切入点(JointPoint)
  • 通知(Advice)
  • 织入(Weave)



posted @ 2020-04-08 15:43  jyqdaisy  阅读(121)  评论(0编辑  收藏  举报