设计模式-代理模式


代理模式的定义

代理模式: 由于某些原因需要给某对象提供一个代理以控制对该对象的访问,这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介

特点

  1. *优点: *
    • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用
    • 代理对象可以扩展目标对象的功能
    • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度
  2. *缺点: *
    • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢
    • 增加了系统复杂度

模式的结构与实现

  1. 模式的结构

    • 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法

    • 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象

    • 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能

    代理模式结构图

  2. 模式的实现

    • 静态代理

      • 代理对象和目标对象实现相同的接口(保证代理对象与目标对象类型一致,面向接口编程代理对象可完全替换目标对象进行传参)
    • 可以做到不修改目标对象功能的前提下对目标对象进行扩展

      • 一旦接口增加方法,目标对象与代理对象都需要维护(缺点)
      //抽象主题
      public interface Dao {
          void save();
      }
      //真实主题
      class UserDao implements Dao {
          @Override
          public void save() {
              System.out.println("保存");
          }
      }
      //代理
      class UserDaoProxy implements Dao{
          private UserDao userDao;
          @Override
          public void save() {
              if(userDao == null) userDao = new UserDao();
              System.out.println("保存前进行的事务"); //
              userDao.save();
              System.out.println("保存后进行的事务");
          }
      }
  • 动态代理(接口代理)

    • 解决了静态代理的缺点

    • 使用JDK提供的api动态的在内存重生成代理对象(又叫jdk代理,接口代理)

    • 代理对象类型为实现接口的类型(不能强转为实现类类型)

      //抽象主题
       public interface Dao {
        void save();
       }
       //真实主题
       class UserDao implements Dao {
           @Override
           public void save() {
               System.out.println("保存");
           }
       }
       //动态代理工厂
       public class ProxyFactory{
           //通过构造函数传入目标对象
           private Object target;
           public ProxyFactory(Object target) {
               this.target = target;
           }
           //生成代理对象的方法
           public Object getProxyInstance(){
               return Proxy.newProxyInstance(
                       target.getClass().getClassLoader(),
                       target.getClass().getInterfaces(),
                       (Object proxy, Method method, Object[] args) ->{
                           Object value = null;
                           if("save".equals(method.getName())) { //只对save方法进行代理
                               System.out.println("开启事务");
                               value = method.invoke(target, args);
                               System.out.println("事务结束");
                           }
                           else value = method.invoke(target,args);
                           return value;
                       }
               );
           }
       }
  • cglib代理(子类代理)

    • 需要引入jar包(spring3.2以上core包中已经集成)

    • 在内存重构建一个子类对象,从而实现对目标对象的扩展

    • 代理类需要实现MethodInterceptor接口

    • 需要代理的类不能为final或static(会报错),同时方法不能final(此时不报错,但是不能拦截该方法)

    //代理工厂
    public class ProxyFactory implements MethodInterceptor{
            //传入目标对象
            private Object target;
            public ProxyFactory(Object target){
                this.target = target;
    }
    //给目标对象创建代理对象
    public Object getInstance(){
        Enhancer en = new Enhancer();        //工具类
        en.setSuperclass(target.getClass());    //设置代理对象父类
        en.setCallback(this)                    //设置回调函数
            //回调函数作用: 执行目标对象的方法会触发执行重写的intercept的方法
        return en.create();                    //创建子类并返回
    }
    //重写的intercept方法    
    @Override
    public Object intercept(Object obj,Method method,object[] args,
    MethodProxy proxy){
        System.out.println(“开始事务”);
        Object value = method.invoke(target,args);    //执行目标对象的方法
        System.out.println(“提交事务”);
        return value;
    }
    }
    

文章作者: Bryson
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bryson !
评论
 上一篇
设计模式-适配器模式 设计模式-适配器模式
适配器模式定义 适配器模式(Adapter): ** 将一个类的接口转换成客户希望的另外一个接口,是的原本由于接口不兼容而不能一起工作的那些类能一起工作,失配模式分为类结构型模式和对象接口型模式**,前者类之间的耦合度比后者高,使用较少
2020-04-07
下一篇 
设计模式-建造者模式 设计模式-建造者模式
建造者模式的定义 *建造者(Builder)模式: * 指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式,它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成,它将变与不变想
2020-03-30
  目录