静态代理模式 (玩转设计完整视频)

什么是代理模式?

为目标对象提供一个替身,以控制对这个对象的访问,进行附加功能增强,从而达到扩展目标对象的功能。比如:添加日志、事务控制、程序耗时等等。

代理模式角色

抽象角色:定义代理角色和真实角色的公共对外方法。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理对象调用。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以增加前置和后置操作。

代理模式UML图

玩转设计布局制图,玩转设计完整视频

代理模式实现方式

  • 静态代理
  • JDK动态代理
  • Cglib动态代理

静态代理定义

被代理对象(即目标对象)和代理对象需要实现共同的接口或继承共同的抽象类,同时代理对象需要关联目标对象。详见UML类图。

静态代理源码示例

下面以用户管理为例,对用户功能进行增强,添加方法入口日志和结束日志。

/**
 * 用户管理接口
 */
public interface IUserService {
  void insert();

  void print();
}
/**
 * 用户管理实现类
 */
public class UserServiceImpl implements IUserService {
  @Override
  public void insert() {
    System.out.println("新增一个用户");
   }

  @Override
  public void print() {
    System.out.println("打印用户信息");
   }
}

/**
 * 用户管理静态代理类
 *
 */
public class UserServiceProxy implements IUserService {
  private IUserService userService;

  public UserServiceProxy(IUserService userService) {
    this.userService = userService;
   }

  /**
   * 对原有insert功能进行增强,增加日志信息
   */
  @Override
  public void insert() {
    System.out.println("新增用户开始");
    userService.insert();
    System.out.println("新增用户成功。");
   }

  /**
   * 对原有print功能进行增强,增加日志信息
   */
  @Override
  public void print() {
    System.out.println("输出用户信息开始");
    userService.print();
    System.out.println("输出用户信息完成。");
   }
}

静态代理客户端测试

public class ClientTest {

  public static void main(String[] args) {
    //创建目标对象
    IUserService userService = new UserServiceImpl();

    //创建代理对象
    IUserService userServiceProxy = new UserServiceProxy(userService);
    
    //调用方法
    userServiceProxy.print();
    System.out.println("====================================");
    userServiceProxy.insert();
   }
}

玩转设计布局制图,玩转设计完整视频

静态代理优缺点

优点:

避免了直接修改目标对象的功能,以代理模式对目标对象进行了功能扩展。

缺点:

代理类需要与目标对象一一对应,可能会产生“类爆炸”,维护工作量巨大。

如果目标对象新增功能,代理类也要同步进行新增升级,可谓牵一发而动全身。

静态代理小结

本章节主要分享了代理模式的定义及3种实现方式,并重点介绍了静态代理的实现和优缺点。下一章节将分享JDK动态代理。

若本文使你受益,还请给予关注、点赞、转发,欢迎拍砖!!!