【设计模式-代理】

定义

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

特点

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

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

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

分类

  • 静态代理(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();
    }
}

优点

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

缺点

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

场景

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

总结

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

相关推荐
龙哥·三年风水6 小时前
活动系统开发之采用设计模式与非设计模式的区别-后台功能总结
设计模式·php·tinkphp6
一头老羊6 小时前
前端常用的设计模式
设计模式
严文文-Chris7 小时前
【设计模式-组合】
设计模式
kimloner8 小时前
工厂模式(二):工厂方法模式
java·设计模式·工厂方法模式
丶白泽11 小时前
重修设计模式-结构型-桥接模式
java·设计模式·桥接模式
南郁12 小时前
把设计模式用起来!(3)用不好模式?之时机不对
设计模式
Lill_bin13 小时前
Lua编程语言简介与应用
开发语言·数据库·缓存·设计模式·性能优化·lua
瞅瞅水16 小时前
设计模式中工厂模式的C语言实现
设计模式
SchneeDuan18 小时前
iOS六大设计原则&&设计模式
ios·设计模式·cocoa·设计原则
Book_熬夜!19 小时前
Python基础(十)——闭包、装饰器、设计模式与多线程编程
开发语言·python·设计模式