【代理模式】

为其他对象提供了一种代理以控制对这个对象的访问。

代理模式是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

【Subject/抽象角色】定义了RealSubject和Proxy的共用接口,这样就可以在任何使用RealSubject的地方都可以使用Proxy

【RealSubject/真实角色】定义Proxy所代表的真实实体

【Proxy/代理角色】保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的方法,这样可以用Proxy替换实体。

【Client/客户】访问代理对象的人

抽象角色类

// 抽象主题类
class Subject {
public:
    virtual void request() const = 0;
};

真实主题类,实现实际的业务逻辑

class RealSubject : public Subject {
public:
    void request() const override {
        std::cout << "RealSubject: Handling request." << std::endl;
    }
};

 代理类:

// 代理类,包含一个对真实主题对象的引用,可以控制对真实主题的访问
class Proxy : public Subject {
private:
    std::shared_ptr<RealSubject> realSubject;

    bool checkAccess() const {
        // 在这里实现访问控制
        std::cout << "Proxy: Checking access before firing a real request." << std::endl;
        return true;
    }

    void logAccess() const {
        // 记录请求的日志
        std::cout << "Proxy: Logging the time of request." << std::endl;
    }

public:
    Proxy(std::shared_ptr<RealSubject> realSubject): realSubject(realSubject) {}

    void request() const override {
        if (this->checkAccess()) {
            this->realSubject->request();
            this->logAccess();
        }
    }
};
void clientCode(const std::shared_ptr<Subject>& subject) {
    // ...
    subject->request();
    // ...
}

 

int main() {
    std::cout << "Client: Executing the client code with a real subject:\n";
    auto realSubject = std::make_shared<RealSubject>();
    clientCode(realSubject);
    std::cout << "\nClient: Executing the same client code with a proxy:\n";
    auto proxy = std::make_shared<Proxy>(realSubject);
    clientCode(proxy);
    return 0;
}

在这个例子中,Proxy类通过持有一个RealSubject对象的引用来控制对RealSubject的访问。在调用RealSubject的request()方法之前,Proxy可以执行一些操作,比如访问控制、缓存、记录日志等。这样,客户端代码就可以透明地使用代理而不是直接访问真实对象,同时增加了额外的行为。 

【代理模式应用】

远程代理(Remote Proxy):为一个对象在不同的地址空间提供局部代表,在客户端和远程服务器之间起到中介的作用。

虚拟代理(Virtual Proxy):根据需要创建开销较大的对象,通过它来存放实例化需要相当长时间的真实对象。

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

智能指引(Smart Reference):当对象被引用时,提供额外的行为,如计数对象引用的次数、检查对象是否被锁定等。

更多推荐