学习设计模式 - 代理模式

Posted timfruit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习设计模式 - 代理模式相关的知识,希望对你有一定的参考价值。

学习设计模式 - 代理模式

一丶定义

   代理模式为另一个对象提供替身或者占位符以控制对这个对象访问, 被代理的对象可以是远程的对象、创建开销大的对象、需要安全控制的对象

 

二丶理解

   2.1) 当一个对象除了处理真正的业务逻辑之外, 还需要增加额外的处理,如事务,打印日志等等, 如果将这些额外逻辑放到原对象中,会造成职责不清晰.
          这时可以使用代理对象代理该对象, 代理对象实现额外逻辑, 真正的业务逻辑则委托给被代理对象处理.这样可以使得职责清晰.


     2.2) 为另一个对象提供一个替身或占位符以控制对这个对象的访问.这也是代理模式和装饰者模式之间的重要区别
          当一个对象是大对象或者消耗资源的对象, 为提高系统性能, 可以使用代理对象暂时替代该对象, 到真正需要的时候才生成该对象.
          当权限不够时,可以使用代理对象限制对该对象的访问.

 

 

三丶静态代理

  技术图片

 

 

  a. 主题

public interface Subject 
    void request();

 

  b. 真实主题

public class RealSubject implements Subject 
    @Override
    public void request() 
        System.out.println("真正业务逻辑...");
    

 

   c. 代理

public class Proxy implements Subject 

    private Subject subject;

    public Proxy(Subject subject) 
        this.subject = subject;
    

    @Override
    public void request() 
        System.out.println("增加事务...");
        subject.request();
    

 

  d. 场景类

/**
 * 静态代理
 *
 *  缺点:
 *      相同的代理方法,却要写多个代理类
 * @author TimFruit
 * @date 19-5-25 下午10:15
 */
public class Client 

    public static void main(String[] args) 
        Proxy proxy=new Proxy(new RealSubject());
        proxy.request();

        Proxy2 proxy2=new Proxy2(new RealSubject2());
        proxy2.request();
    

 

  运行结果为:

增加事务...
真正业务逻辑...
增加事务...
真正的业务处理2...

 

  还有类似的代码Proxy2没有贴出来, 完整代码可以点此查看

 

四丶JDK动态代理

  由上面代码可知, 使用静态代理需要为每个"被代理的类", 实现代理类, 当代理类实现方法相同时, 将会产生很多繁琐重复的代码, 因此有了动态代理, 动态代理一般有两种常用的实现, 一种是jdk动态代理, 一种是cglib动态代理. 这里展示的是jdk动态代理.

 

/**
 * 实现jdk自带的接口
 * 写一个较为通用的"切面"类
 * @author TimFruit
 * @date 19-5-26 上午10:57
 */
public class ProxyInvocationHandler implements InvocationHandler 

    private Object target;

    public ProxyInvocationHandler(Object target) 
        this.target = target;
    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("增加事务...");
        return method.invoke(target, args);
    

  

  场景类:

/**
 * JDK动态代理
 *  <p>
 *      好处是写一个较为通用的"切面"类就可以了, 动态生成对应的代理类, 减少代码量
 *
 * @author TimFruit
 * @date 19-5-26 上午11:00
 */
public class Client 
    public static void main(String[] args) 

        RealSubject subject=new RealSubject();
        InvocationHandler proxyInvocationHandler=new ProxyInvocationHandler(subject);
        //动态生成代理类
        Subject subjectProxy= (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]Subject.class, proxyInvocationHandler);
        subjectProxy.request();



        RealSubject2 subject2=new RealSubject2();
        InvocationHandler proxyInvocationHandler2=new ProxyInvocationHandler(subject2);
        // 动态生成代理类
        Subject2 subjectProxy2= (Subject2) Proxy.newProxyInstance(RealSubject2.class.getClassLoader(), new Class[]Subject2.class, proxyInvocationHandler2);
        subjectProxy2.request();
    

 

   运行结果为:

增加事务...
真正业务逻辑...
增加事务...
真正的业务处理2...

 

   完整代码点此查看

 

 

 学习资料:

  <Head First 设计模式>

  <设计模式之禅>

 

 

以上是关于学习设计模式 - 代理模式的主要内容,如果未能解决你的问题,请参考以下文章

尚硅谷设计模式学习(13)---[代理模式(Proxy)---静态代理,动态代理,Cglib代理]

设计模式学习笔记之代理模式

代理模式——HeadFirst设计模式学习笔记

软件设计模式学习(十六)代理模式

软件设计模式学习(十六)代理模式

swift设计模式学习 - 代理模式