【设计模式In Java】十一、代理模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CL_YD/article/details/88077403

代理模式

定义

代理模式(Proxy Pattern):给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代理等,它们应用于不同的场合,满足用户的不同需求。

  • 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
  • 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
  • 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
  • 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
  • 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。

场景

代理模式在开发过程用到很多,但是并不是直接在代码中使用,而是各种框架和工具提供的,比如spring-aop、mockito、mybatis、spring feign client等等,这些工具的共同点都是简化开发者使用代理模式的方式,可以通过配置的方式实现代理而不是使用硬编码的方式实现代理,所以几乎只有在写一些公共工具的时候才会考虑到代理,比如权限验证框架等。

现在有一个权限验证系统,不同用户有不同的权限,可能增加新的权限,可以用代理模式来验证用户的权限。

UML类图

在这里插入图片描述

代码

proxy
示例:

public class TestProxy {

    @Test
    public void test() {
        PermissionProxy proxy = new PermissionProxy(new DeletePermission());
        proxy.execute(new User("Ashe", new HashSet<>(Arrays.asList("update", "delete"))), "target A");

        proxy.execute(new User("Bob", null), "target A");
        /*
        Ashe execute delete on target A...
        Bob has no delete permission...
         */
    }

}

总结

代理模式有很多优点,包括符合开闭原则的低耦合、细节隐藏、增强扩展,基于不同类型的代理模式也各有优点:

  • 远程代理为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。
  • 虚拟代理通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。
  • 缓冲代理为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。
  • 保护代理可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。

但是代理模式可能会让系统运行变慢,特别是在那些高并发并且对响应时间很敏感的场景下,比如Web应用,如果对没个请求都做一次代理,代理类中有做了很多复杂的检查和增强,那么势必会让请求速度明显变慢,所以准备使用代理模式的时候必须考虑到并发和响应速度。

代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:

  • 当客户端对象需要访问远程主机中的对象时可以使用远程代理。
  • 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
  • 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
  • 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
  • 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

猜你喜欢

转载自blog.csdn.net/CL_YD/article/details/88077403
今日推荐