【设计模式-代理】

定义

代理模式是一种结构型设计模式,它提供了对象的替代者或占位符,用来控制对这个对象的访问。通过代理模式,一个类可以代表另一个类来执行某些操作 。这种模式常用于增强对象的功能或控制对对象的访问

特点

控制访问:代理模式可以控制对目标对象的访问,甚至可以在访问前后进行某些操作。

增强功能:代理可以在不修改目标对象的前提下,增强目标对象的功能。

延迟加载:代理模式可以实现对象的延迟加载,只有在真正需要的时候才创建对象。

分类

  • 静态代理(Static Proxy):代理类在编译时已经确定,通常由开发者手动编写。
  • 动态代理(Dynamic Proxy):代理类在运行时动态生成,通常通过反射机制实现。
  • 虚拟代理(Virtual Proxy):用于延迟加载对象,只有在需要时才创建对象。
  • 保护代理(Protection Proxy):控制对对象的访问权限。
  • 远程代理(Remote Proxy):用于控制对远程对象的访

组成

  • 抽象主题角色:定义了被代理角色和代理角色的共同接口或者抽象类。

  • 被代理角色:实现或者继承抽象主题角色,定义实现具体业务逻辑的实现。

  • 代理角色:实现或者继承抽象主题角色,持有被代理角色的引用,控制和限制被代理角色的实现,并且拥有自己的处理方法(预处理和善后)

代码

静态代理

java 复制代码
// 抽象接口
public interface Subject {
    void request();
}

// 真实对象,实现具体的业务逻辑
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理类,控制对 RealSubject 的访问
public class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("Proxy: Performing additional actions before forwarding request to RealSubject.");
        realSubject.request();
        System.out.println("Proxy: Performing additional actions after forwarding request to RealSubject.");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
}

动态代理

java 复制代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 真实对象,实现具体的业务逻辑
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 动态代理处理器
class ProxyInvocationHandler implements InvocationHandler {
    private final Object realSubject;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxy: Performing actions before invoking real subject.");
        Object result = method.invoke(realSubject, args);
        System.out.println("Proxy: Performing actions after invoking real subject.");
        return result;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();

        // 创建代理对象
        Subject proxyInstance = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new ProxyInvocationHandler(realSubject)
        );

        // 调用代理对象的方法
        proxyInstance.request();
    }
}

优点

  • 职责分离:通过代理模式,可以将真实对象的实现与控制访问的逻辑分离,符合单一职责原则。
  • 增强功能:在不修改真实对象的情况下,通过代理类可以增加额外的功能,如日志记录、性能统计、安全控制等。
  • 灵活性:代理模式使得在不改变客户端代码的情况下,能够动态地更换不同的代理对象。

缺点

  • 增加复杂性:引入代理模式会增加系统的复杂性,尤其是在使用动态代理时,可能会让代码变得难以理解和调试。
  • 性能开销:代理模式在某些情况下会增加系统的开销,特别是在频繁调用的情况下,代理对象的创建和方法调用的间接性可能会影响性能。

场景

  • 远程代理:需要通过代理对象来控制对远程对象的访问。
  • 虚拟代理:需要延迟创建资源消耗大的对象,或者只在需要时创建对象。
  • 保护代理:需要控制对对象的访问权限,如在应用程序中根据用户的权限控制对某些功能的访问。
  • 缓存代理:需要对访问频繁的对象或结果进行缓存,以减少资源消耗或提高性能。

总结

代理模式通过引入代理对象控制对目标对象的访问,适用于需要增强功能、延迟加载、权限控制、远程访问等场景。静态代理通过手动编写代理类来控制对象访问,而动态代理则通过运行时生成代理类提供了更灵活的解决方案。虽然代理模式增加了系统的复杂性,但它在特定场景下能带来更好的代码结构和更高的灵活性。

相关推荐
金池尽干24 分钟前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨38 分钟前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉10 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点10 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰10 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus10 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵10 小时前
设计模式-迭代器
设计模式
lexusv8ls600h12 小时前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式
sniper_fandc15 小时前
抽象工厂模式
java·设计模式·抽象工厂模式
无敌岩雀17 小时前
C++设计模式结构型模式———外观模式
c++·设计模式·外观模式