设计模式之代理模式(结构型)

Posted 思想累积

tags:

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

1、简介

1.1 代理模式定义

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

1.2 代理模式类型

  • 静态代理:手动编写代理类,代理类引用被代理对象
  • 动态代理:在内存中构建的,不用手动编写代理类
  • Cglib 代理:子类代理,在内存中构建一个子类对象来实现对目标功能的扩展

1.3 优缺点

优点:

  • 代理对象可以扩展目标对象的功能
  • 代理模式能将客户端与目标对象分离,降低了系统的耦合度
  • 代理模式可以在客户端和目标对象之间起到一个中介作用和保护目标对象的作用

缺点:

  • 增加了系统复杂度
  • 客户端和目标对象之间增加代理对象,会造成请求处理速度变慢

1.4 代理模式结构

  • 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法
  • 真是主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的的真实对象,是最终要引用对象
  • 代理(Proxy)类:提供了与真实主题相同的接口,内部含有对真实主题的引用,可以访问、扩展或控制真实主题的功能

1.5 代理模式的应用场景

  • 安全代理:控制不同种类客户对真实对象的访问
  • 远程代理:隐藏目标对象存在于不同地址空间的事实,方便客户端访问。

2、静态代理

2.1 静态代理实现

首先创建一个接口(Subject),然后创建具体的实现类(RealSubject)实现该接口,之后创建一个代理类 (Proxy)实现相同的接口。

不同之处在于,具体实现类(RealSubject)中的方法只是将接口中定义的方法的业务逻辑实现,代理类中只是调用具体类中的方法即可。我们在使用接口中的方式时,直接调用代理类的方法即可。

2.2 代码实现

/**
 * 抽象主题
 */
public interface Subject 

    void request();



/**
 * 具体的实现类,被代理角色
 */
public class RealSubject implements Subject 

    @Override
    public void request() 
        System.out.println("真实主题方法");
    



/**
 * 代理类
 */
public class Proxy implements Subject 

    private RealSubject realSubject;

    public void preRequest() 
        System.out.println("访问之前的预处理");
    

    public void postRequest() 
        System.out.println("访问之后的处理");
    

    @Override
    public void request() 
        if (realSubject == null) 
            realSubject = new RealSubject();
        
        preRequest();
        realSubject.request();;
        postRequest();
    



/**
 * 代理类调用
 */
public class ProxyTest 

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



以上代码是我们直接编写好后编译的,而不是在程序运行过程中动态生成的,所以是为静态代理的应用,代理模式可以在不修改被代理对象的基础上,通过扩展代理类来实现功能的增强

3、动态代理

3.1 JDK 动态代理

抽象接口

/**
 * 抽象接口
 */
public interface Subject 

    public void doSomething();


被代理对象

/**
 * 被代理对象
 */
public class RealSubject implements Subject 
    @Override
    public void doSomething() 
        System.out.println("被代理对象方法 doSomething()");
    

代理类

/**
 * 代理的实现类,如果代理的方法被调用,代理会通知和转发给 InvocationHandler 的实现类,由它调用 invoke() 去处理
 */
public class ProxyHandler implements InvocationHandler 

    private Object proxied;

    public ProxyHandler(Object proxied) 
        this.proxied = proxied;
    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("代理类前置处理~~~");
        Object obj = method.invoke(proxied, args);
        System.out.println("代理类后置处理~~~");
        return obj;
    

测试

/**
 * 测试代理
 */
public class JDKProxyTest 

    public static void main(String[] args) 
        RealSubject realSubject = new RealSubject();
        Class[] clas = Subject.class;
        // 使用 java.lang.reflect.Proxy 的 newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象
        Subject subject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), clas, new ProxyHandler(realSubject));
        subject.doSomething();
        System.out.println("代理对象的类型 : " + subject.getClass().getName());
        System.out.println("代理对象所在类的父类型 : " + subject.getClass().getGenericSuperclass());
    


/**
* 输出数据:
* 代理类前置处理~~~
* 被代理对象方法 doSomething()
* 代理类后置处理~~~
* 代理对象的类型 : com.sun.proxy.$Proxy0
* 代理对象所在类的父类型 : class java.lang.reflect.Proxy
**/

以上是关于设计模式之代理模式(结构型)的主要内容,如果未能解决你的问题,请参考以下文章

结构型模式之代理模式

结构型设计模式之代理模式

设计模式之代理模式

设计模式——结构型模式之代理模式

设计模式之代理模式(结构型)

结构型模式之代理模式