【设计模式】代理模式

377 阅读4分钟

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理,以控制对这个对象的访问。代理模式通常用于延迟创建开销较大的对象,控制对对象的访问权限,或在访问对象时进行一些操作,如日志记录、性能监控等。

代理模式的分类

代理模式根据不同的应用场景,可以分为以下几类:

  1. 静态代理:在编译时由程序员手动创建或工具自动生成代理类。
  2. 动态代理:在运行时通过反射机制动态生成代理类。
  3. 保护代理:控制对原始对象的访问,适合对象有不同访问权限时使用。
  4. 虚拟代理:通过代理对象来控制对耗资源对象的访问,延迟实际对象的创建。
  5. 远程代理:为位于不同地址空间的对象提供局部代理对象,控制对远程对象的访问。

代理模式的结构

代理模式的关键在于代理类(Proxy)和被代理类(RealSubject)之间的关系。具体结构如下:

  1. Subject(主题)

    • 定义代理类和被代理类的共同接口,使得代理类可以作为被代理类的替代品。
  2. RealSubject(真实主题)

    • 实现具体的业务逻辑。
  3. Proxy(代理类)

    • 持有一个对真实主题的引用,并实现主题接口。
    • 控制对真实主题的访问,可以在调用真实主题的方法前后进行额外的操作。

代理模式的实现

以下是使用Java实现代理模式的详细代码示例。

1. 定义主题接口


public interface Subject {
    void request();
}

2. 实现真实主题类


public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

3. 实现代理类


public class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("Proxy: Logging request.");
        realSubject.request();
    }
}

4. 测试代理模式


public class ProxyPatternTest {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}

运行结果:


Proxy: Logging request.
RealSubject: Handling request.

代理模式在Java中的应用

在Java中,代理模式有着广泛的应用,以下是一些常见的应用场景:

  1. Java RMI(远程方法调用)

    • 使用远程代理在不同的Java虚拟机之间进行方法调用。
  2. 动态代理

    • Java提供了动态代理机制,通过 java.lang.reflect.Proxy 类可以在运行时创建代理类。
  3. AOP(面向切面编程)

    • 通过代理模式实现方法的前置和后置处理,例如Spring AOP。

Android中的应用

在 Android 开发中,代理模式同样有着广泛的应用。例如:

  1. AIDL(Android Interface Definition Language)

    • AIDL 生成的代理类用于进程间通信(IPC),代理类在客户端与服务端之间传递消息。
  2. 动态代理

    • 使用动态代理实现 Retrofit 等网络请求库,生成网络请求接口的代理类,处理网络请求和响应

Java动态代理示例

使用Java的动态代理机制,可以在运行时创建代理对象,并在方法调用前后执行额外操作。


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public interface Subject {
    void request();
}

public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

public class ProxyHandler implements InvocationHandler {
    private Object realSubject;

    public ProxyHandler(Object realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxy: Logging request.");
        return method.invoke(realSubject, args);
    }
}

public class DynamicProxyTest {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxyInstance = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new ProxyHandler(realSubject)
        );

        proxyInstance.request();
    }
}

运行结果:


Proxy: Logging request.
RealSubject: Handling request.

代理模式的优缺点

优点

  1. 隔离对象:代理模式在客户端和真实对象之间引入了代理对象,隔离了客户端和对象的耦合。
  2. 控制访问:代理对象可以在访问真实对象前后进行额外的操作,控制对真实对象的访问。
  3. 延迟加载:虚拟代理可以实现对象的延迟加载,减少系统资源的开销。

缺点

  1. 性能开销:引入代理对象会增加一定的性能开销,尤其是在使用动态代理时。
  2. 实现复杂:代理模式的实现相对复杂,可能会增加系统的复杂性。

总结

代理模式是一种非常实用的设计模式,通过在客户端和真实对象之间引入代理对象,可以实现对真实对象的访问控制、延迟加载、性能监控等功能。在实际开发中,合理地运用代理模式,可以提高代码的灵活性和可维护性,同时需要注意性能开销和实现复杂性的问题。希望本文的介绍能够帮助你更好地理解和应用代理模式。