《一天一模式》— 代理模式

1、代理模式的概念

代理(Proxy)是一种设计模式,提供了间接对目标对象进行访问的方式。即经过代理对象访问目标对象,这样作的好处是,能够在目标对象实现的功能上,增长额外的功能补充,即扩展目标对象的功能.。java

2、何时使用代理模式

代理类主要负责为委托类作消息预处理、消息过滤。把消息转发给委托类,以及过后对返回结果的处理等。数据库

代理类自己并不真正实现服务,而是经过调用委托类的相关方法,来提供特定的服务。真正的业务功能仍是由委托类来实现,可是能够在业务功能执行的先后加入一些公共的服务。编程

例如咱们想给项目加入缓存、日志这些功能,咱们就可使用代理类来完成,而不必打开已经封装好的委托类。设计模式

3、怎么使用代理模式

以上面的例子来讲,加入系统原有一个查询用户信息的功能,因为项目迭代,要在查询用户信息时,先读取缓存,缓存中没有在从库中查询。缓存

这个场景就可使用代理模式来实现,不须要修改原有的从库中查询的方法,只须要加入代理模式就能够解决。框架

下面来看下用Java方式实现代理模式要怎么作。测试

3.1 实现方式

// 用户服务接口
public interface UserService {

    void findById();

}

// 查询用户的实现类
public class UserServiceImpl implements UserService {

    public void findById() {
        System.out.println("从数据库查询用户信息。");
    }
}

// 代理类
public class UserProxy implements UserService {

    // 真正处理业务的对象
    private UserService userService;

    public UserProxy(UserService userService) {
        this.userService = userService;
    }

    // 代理方法
    public void findById() {
        System.out.println("从缓存中查询用户信息。");
        System.out.println("缓存中未查询到用户信息。");
        userService.findById();
    }

}

public class Client {

    public static void main(String[] args) {
        // 使用代理模式以前,已经封装好方法,直接从数据库中查询。
        UserService userService = new UserServiceImpl();
        userService.findById();
        System.out.println();
        // 使用代理模式加入从缓存查询
        UserService userProxy = new UserProxy(userService);
        userProxy.findById();

    }

}

// 输出:
//从数据库查询用户信息。
//
//从缓存中查询用户信息。
//缓存中未查询到用户信息。
//从数据库查询用户信息。

代理模式如上面的作法,先建立代理类并实现被代理类的接口,而后在代理类中定义一个被代理类的实例,实例化时注入进来。this

关键在于代理方法,代理方法中调用被代理对象,能够在调用前,调用后加入代理类想要的业务,就是作法就是代理模式。spa

3.2 代理模式的好处

  • 职责清晰:具体角色是实现具体的业务逻辑,不用关心其余非本职责的事务,经过后期的代理完成一件事务,代码清晰。在某些状况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象能够在客户类和委托对象之间起到中介的做用,其特征是代理类和委托类实现相同的接口。
  • 高扩展性:具体主题角色随时会发生变化,可是只要实现了接口,接口不变,代理类就能够不作任何修改继续使用,符合“开闭原则”。

3.3 代理模式的几种类型

Java中实现代理模式可分为三种:设计

  • 静态代理(上面的例子): 在使用静态代理时,被代理对象与代理对象须要一块儿实现相同的接口或者是继承相同父类,所以要定义一个接口或抽象类。这种作法简单直接,可读性高;
  • 动态代理:动态代理的主要特色就是可以在程序运行时JVM才为被代理对象生成代理对象。常说的动态代理也叫作JDK代理也是一种接口代理,JDK中生成代理对象的代理类就是Proxy,所在包是java.lang.reflect;
  • Cglib代理:Cglib代理也叫做子类代理,是在内存中构建一个子类对象从而实现对目标对象功能的扩展,使用这种代理技术无需实现接口;

几种代理技术就不在设计模式中详细说明了,会另外写一篇调研代理的博客文章。

4、总结

业务上,当须要在调用某方法以前或以后进行相对应的处理,但又不想或无条件去修改要调用的方法,一般是不想,首先是要符合开闭原则,其次是在不修改原来的代码,能够减小测试范围。这种情形下,很是适合使用代理模式。

代理模式使用的很是普遍,尤为其中的动态代理技术,不少开源开发框架都在应用。特别在AOP编程模式下。

好比使用Spring的AOP,就是使用动态代理和Cglib代理来实现的。在使用AOP框架时,须要关注几个名词:

  • 切面(Aspect)

  • 切入点(JointPoint)

  • 通知(Advice)

  • 织入(Weave)

在此不对这些作过多说明了,相关信息能够搜索AOP编程。

以上就是我对代理模式的一些理解,有不足之处请你们指出,谢谢。

相关文章
相关标签/搜索