java设计模式(六)代理模式(Proxy Pattern)

1、模式介绍:

代理模式(Proxy Pattern)是一种结构型设计模式,它允许你在不改变客户端代码的情况下,向某个对象提供一个代理,以控制对该对象的访问。代理对象通常会在实际对象的方法调用前后添加一些附加逻辑,如权限控制、懒加载、日志记录等。

代理模式涉及以下几个角色:

接口(Subject):定义了代理类和真实类共同的接口。

真实类(RealSubject):实现了接口的具体类,它是真正执行操作的对象。

代理类(Proxy):也实现了接口,持有真实类的引用,并在调用真实类的方法前后进行一些额外的处理。

2、应用场景:

远程代理(Remote Proxy):为一个对象在不同地址空间提供局部代表。典型应用是 RMI(远程方法调用)。

虚拟代理(Virtual Proxy):根据需要创建开销大的对象。它在真正需要时才创建对象。

保护代理(Protection Proxy):控制对原始对象的访问。通常用于对象应该有不同的访问权限。

智能引用(Smart Reference):在访问对象时提供额外的功能,例如引用计数、缓存等。

3、优点:

控制对真实对象的访问,增加系统的灵活性。

可以对真实对象进行扩展,而不修改其代码。

提供了对目标对象额外的操作,如权限控制、延迟加载、日志记录等。

4、缺点:

增加了系统的复杂度,尤其是在使用保护代理时。

可能会影响请求的处理速度,因为增加了间接层。

5、代码实现:

/**
 * 代理接口
 *
 * @author FM_南风
 * @date 2024/6/25 13:28
 */
public interface Subject {
    void request();
}

/**
 * 实体类
 *
 * @author FM_南风
 * @date 2024/6/25 13:28
 */
public class RealSubject implements Subject{
    @Override
    public void request() {
        System.out.println("实体类的请求");
    }
}

/**
 * 代理类
 *
 * @author FM_南风
 * @date 2024/6/25 13:30
 */
public class Proxy implements Subject {
    private RealSubject realSubject;
    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.request();
        postRequest();
    }

    private void preRequest() {
        System.out.println("代理类: 前置处理");
    }

    private void postRequest() {
        System.out.println("代理类: 后置处理");
    }
}

/**
 * 应用
 *
 * @author FM_南风
 * @date 2024/6/25 13:31
 */
public class ProxyClient {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}

6、结果展示:

java设计模式(六)代理模式(Proxy Pattern)_第1张图片
7、拓展动态代理:

还可以使用动态代理来实现代理模式,它使用 java.lang.reflect.Proxy 类和 InvocationHandler 接口来动态地创建代理对象。动态代理可以在运行时动态地将代理逻辑添加到真实对象中,而不需要在编译时显式地创建代理类。

/**
 * 动态代理
 *
 * @author FM_南风
 * @date 2024/6/25 13:37
 */
public class ProxyInvocationHandler implements InvocationHandler {
    private Object realSubject;

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

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("动态代理类: 前置处理");
        Object result = method.invoke(realSubject, objects);
        System.out.println("动态代理类: 后置处理");
        return result;
    }
}

/**
 * 动态代理应用
 *
 * @author FM_南风
 * @date 2024/6/25 13:39
 */
public class ProxyInvocationClient {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxy = (Subject) Proxy.newProxyInstance(
                realSubject.getClass().getClassLoader(),
                realSubject.getClass().getInterfaces(),
                new ProxyInvocationHandler(realSubject)
        );

        proxy.request();
    }
}

java设计模式(六)代理模式(Proxy Pattern)_第2张图片

你可能感兴趣的:(java设计模式,java,设计模式,代理模式)