【设计模式】——代理模式(Proxy Pattern)

目录

引言

一、代理模式的基本概念

核心思想

代理模式的结构

代理模式的类型

UML图

应用场景

二、代理模式的优点与缺点

优点

缺点

三、C++实现代理模式

静态代理

动态代理

四、结论


引言

在软件开发中,设计模式是一种可复用的解决方案,用于解决常见的设计问题。代理模式(Proxy Pattern)是结构型设计模式的一种,它为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,可以在不改变客户端代码的情况下增强或控制对象的访问。本文将详细探讨代理模式在C++中的实现和应用。

一、代理模式的基本概念

核心思想

代理模式的核心思想是为其他对象提供一个代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,可以拦截对实际对象的访问,并在访问前后执行额外的操作。代理模式主要分为静态代理和动态代理两种类型,其中动态代理在运行时动态生成代理类,更加灵活。

代理模式的结构

代理模式主要包含以下几个角色:

  • 抽象主题(Subject):通过接口或抽象类声明真实主题和代理的公共方法。
  • 真实主题(RealSubject):实现抽象主题角色,定义代理所代表的真实对象。
  • 代理主题(Proxy):包含对真实主题的引用,从而可以操作真实主题对象;同时可以提供额外的功能来扩展真实主题的行为。

代理模式的类型

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

  • 远程代理:用于访问远程对象,隐藏远程调用的细节。
  • 虚拟代理:用于延迟对象的创建,直到真正需要时才创建对象。
  • 保护代理:控制对对象的访问权限,根据访问者的权限决定是否允许访问。
  • 智能代理:在调用对象的方法时,执行额外的操作,如日志记录、性能监控等。

UML图

应用场景

代理模式在软件开发中有广泛的应用场景,包括但不限于:

  • 远程对象访问:在分布式系统中,通过代理访问远程对象。
  • 资源优化:延迟加载大型对象或资源,如图片、视频等。
  • 访问控制:实现不同用户的访问权限控制。
  • 日志记录:在方法调用前后记录日志,便于问题追踪和性能分析。

二、代理模式的优点与缺点

优点

  1. 增强功能:代理模式能够在不修改原有对象代码的情况下,通过代理对象对原有对象的功能进行增强。例如,增加额外的权限检查、日志记录、事务处理、性能统计等功能。

  2. 控制访问:代理模式能够控制对真实对象的访问,特别是在远程通信或分布式系统中,代理对象可以作为本地资源的代表,隐藏远程对象的复杂性。

  3. 降低耦合度:客户端通过代理对象间接访问真实对象,降低了客户端与真实对象之间的耦合度,使得系统更加灵活,易于维护和扩展。

  4. 实现延迟加载:代理模式可以实现懒加载(Lazy Loading),即只有在真正需要时才创建或加载真实对象,这有助于节省系统资源,提高性能。

  5. 智能引用:在代理对象中,可以加入对真实对象的引用计数,从而控制真实对象的生命周期,实现智能引用管理。

缺点

  1. 增加系统复杂性:代理模式在系统中增加了额外的代理类,使得系统的类结构变得更加复杂,增加了理解和维护的难度。

  2. 请求处理速度变慢:由于客户端请求需要通过代理对象转发给真实对象,因此相比直接访问真实对象,请求的处理速度会变慢。特别是在代理对象中添加了大量额外处理逻辑时,这种性能损失会更加明显。

  3. 增加额外开销:代理对象本身需要占用一定的系统资源(如内存),并且每次调用都需要经过代理对象进行转发,这会增加系统的额外开销。特别是在创建大量代理对象时,这种开销会更加显著。

  4. 可能破坏封装性:如果代理对象直接暴露了真实对象的接口或内部状态,那么可能会破坏原有对象的封装性。因此,在设计代理对象时需要格外注意其接口设计,确保不会泄露不应暴露的信息。

  5. 适用场景有限:虽然代理模式在很多场景下都非常有用,但并不是所有情况都适合使用代理模式。在某些情况下,如果直接访问真实对象更加简单高效,那么使用代理模式可能会带来不必要的复杂性。因此,在选择使用代理模式时需要仔细考虑其适用性和必要性。

三、C++实现代理模式

静态代理

静态代理是在编译时就已经确定了代理类和被代理类的关系。以下是C++中实现静态代理的一个简单示例:

#include <iostream>  
#include <memory>  
  
// 抽象主题  
class ISubject {  
public:  
    virtual ~ISubject() = default;  
    virtual void Request() = 0;  
};  
  
// 真实主题  
class RealSubject : public ISubject {  
public:  
    void Request() override {  
        std::cout << "RealSubject::Request() is called." << std::endl;  
    }  
};  
  
// 代理主题  
class ProxySubject : public ISubject {  
private:  
    std::shared_ptr<RealSubject> realSubject;  
  
public:  
    ProxySubject() : realSubject(std::make_shared<RealSubject>()) {}  
  
    void Request() override {  
        std::cout << "ProxySubject::BeforeRequest()" << std::endl;  
        realSubject->Request();  
        std::cout << "ProxySubject::AfterRequest()" << std::endl;  
    }  
};  
  
// 客户端  
int main() {  
    std::shared_ptr<ISubject> subject = std::make_shared<ProxySubject>();  
    subject->Request();  
    return 0;  
}

动态代理

C++标准库中没有直接支持动态代理的机制,但可以通过一些库(如CGLib或Boost.Asio等)来实现类似的功能。这里我们主要讨论概念,不深入具体实现细节。

四、结论

代理模式是一种非常有用的设计模式,它通过引入代理对象来控制对实际对象的访问,增强了系统的灵活性和可扩展性。在C++中,虽然标准库没有直接支持动态代理,但我们可以通过静态代理或借助第三方库来实现类似的功能。通过合理使用代理模式,我们可以使代码更加清晰、易于维护,并提升系统的整体性能。

  • 29
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J^T

谢谢帅哥/美女

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值