23设计模式之代理模式-种类 实际应用场景

代理模式代码

#include <iostream>
#include <string>

// 抽象主题接口
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 {
public:
    Proxy(Subject* real_subject) : real_subject_(real_subject) {}

    void request() const override {
        if (checkAccess()) {
            real_subject_->request();
        } else {
            std::cout << "Proxy: Access denied." << std::endl;
        }
    }

private:
    bool checkAccess() const {
        // 检查权限...
        return true; // 这里简单返回true,表示有权限
    }

    Subject* real_subject_;
};

int main() {
    // 创建真实主题对象
    RealSubject real_subject;

    // 创建代理对象并传入真实主题对象
    Proxy proxy(&real_subject);

    // 通过代理对象调用请求
    proxy.request();

    return 0;
}
在这个示例中,我们有一个抽象主题类 Subject,定义了一个虚拟的请求方法 request。RealSubject 是具体的主题类,实现了 request 方法,用于处理真正的请求。

Proxy 是代理类,也实现了 Subject 接口。它包含了一个指向 RealSubject 对象的成员变量,并在请求方法中对权限进行了检查。如果权限通过,代理会将请求转发给真正的主题对象处理,否则拒绝访问。

在 main 函数中,我们创建了一个真实主题对象和一个代理对象,然后通过代理对象调用请求方法。代理对象会根据权限决定是否转发请求给真实主题对象。

代理类的作用

代理类在设计模式中扮演着重要的角色,它能够为其他对象提供一个代理或者占位符,以控制对这个对象的访问。代理类通常包含与被代理对象相同的接口,使得代理对象可以替代被代理对象,并对其进行额外的控制、管理或者增强。代理类的作用包括但不限于以下几个方面:

远程代理(Remote Proxy): 在分布式系统中,代理类可以作为远程对象的本地代表,隐藏了真实对象存在于不同地址空间的事实,使得客户端可以像调用本地对象一样调用远程对象。

虚拟代理(Virtual Proxy): 当创建对象需要大量资源或者时间时,代理类可以充当对象的占位符,延迟创建真实对象,直到真正需要使用它时才进行实例化,从而提高系统的性能和效率。

保护代理(Protection Proxy): 代理类可以控制对真实对象的访问权限,只有经过授权的用户才能访问真实对象,从而保护真实对象免受未经授权的访问。

智能引用代理(Smart Reference Proxy): 代理类可以在调用真实对象的方法前后执行额外的操作,比如记录日志、实现缓存、懒加载等,从而增强真实对象的功能。

缓存代理(Caching Proxy): 代理类可以缓存真实对象的结果,以减少对真实对象的重复调用,提高系统的性能。

日志记录代理(Logging Proxy): 代理类可以记录对真实对象的访问日志,用于跟踪和调试系统的运行情况。

总的来说,代理类可以根据具体的需求和场景,对被代理对象进行各种形式的控制、管理和增强,从而提高系统的灵活性、可维护性和可扩展性。


下面是一个简单的示例代码,演示了一个日志记录代理:

cpp
复制代码
#include <iostream>
#include <string>

// 抽象主题接口
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 LoggingProxy : public Subject {
public:
    LoggingProxy(Subject* real_subject) : real_subject_(real_subject) {}

    void request() const override {
        log("Before request");
        real_subject_->request();
        log("After request");
    }

private:
    void log(const std::string& message) const {
        std::cout << "LoggingProxy: " << message << std::endl;
    }

    Subject* real_subject_;
};

int main() {
    // 创建真实主题对象
    RealSubject real_subject;

    // 创建日志记录代理对象并传入真实主题对象
    LoggingProxy proxy(&real_subject);

    // 通过代理对象调用请求
    proxy.request();

    return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。

然后我们定义了一个日志记录代理类 LoggingProxy,它也实现了 Subject 接口。在 LoggingProxy 中,我们重载了 request 方法,在调用真实主题对象的 request 方法之前和之后,分别记录了日志。

在 main 函数中,我们创建了一个真实主题对象和一个日志记录代理对象,并通过代理对象调用了请求方法。代理对象在调用真实主题对象的方法前后,分别记录了日志。

远程代理
远程代理(Remote Proxy)用于在分布式系统中代表远程对象。它隐藏了真实对象存在于不同地址空间的事实,使得客户端可以像调用本地对象一样调用远程对象。下面是一个简单的示例代码:

cpp
复制代码
#include <iostream>
#include <string>

// 抽象主题接口
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 RemoteProxy : public Subject {
public:
    RemoteProxy(const std::string& remote_address) : remote_address_(remote_address) {}

    void request() const override {
        // 在这里实现远程调用逻辑,这里只是简单地打印信息
        std::cout << "RemoteProxy: Making remote request to " << remote_address_ << std::endl;

        // 创建真实主题对象的代理
        RealSubject real_subject;
        real_subject.request();
    }

private:
    std::string remote_address_;
};

int main() {
    // 创建远程代理对象并指定远程地址
    RemoteProxy proxy("http://example.com/remote");

    // 通过代理对象调用请求
    proxy.request();

    return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。

然后我们定义了一个远程代理类 RemoteProxy,它也实现了 Subject 接口。在 RemoteProxy 中,我们实现了 request 方法,其中包含了远程调用的逻辑。这里的远程调用逻辑只是简单地打印了一条信息,并创建了真实主题对象的代理来处理请求。

在 main 函数中,我们创建了一个远程代理对象,并通过代理对象调用了请求方法。代理对象在调用请求方法时会执行远程调用的逻辑。

虚拟代理(Virtual Proxy)延迟创建真实对象,直到真正需要使用它时才进行实例化。下面是一个简单的示例代码:

cpp
复制代码
#include <iostream>
#include <string>

// 抽象主题接口
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 VirtualProxy : public Subject {
public:
    void request() const override {
        // 延迟创建真实主题对象
        if (!real_subject_) {
            real_subject_ = new RealSubject;
        }

        // 使用真实主题对象处理请求
        real_subject_->request();
    }

private:
    RealSubject* real_subject_{nullptr};
};

int main() {
    // 创建虚拟代理对象
    VirtualProxy proxy;

    // 通过代理对象调用请求
    proxy.request();

    return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。

然后我们定义了一个虚拟代理类 VirtualProxy,它也实现了 Subject 接口。在 VirtualProxy 中,我们实现了 request 方法,其中延迟创建了真实主题对象,直到真正需要使用它时才进行实例化。

在 main 函数中,我们创建了一个虚拟代理对象,并通过代理对象调用了请求方法。代理对象在调用请求方法时会延迟创建真实主题对象,并使用它来处理请求。


保护代理(Protection Proxy)控制对真实对象的访问权限,只有经过授权的用户才能访问真实对象。下面是一个简单的示例代码:

cpp
复制代码
#include <iostream>
#include <string>

// 抽象主题接口
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 ProtectionProxy : public Subject {
public:
    ProtectionProxy(const std::string& user) : user_(user) {}

    void request() const override {
        // 检查权限
        if (checkAccess()) {
            // 如果权限通过,则使用真实主题对象处理请求
            real_subject_.request();
        } else {
            std::cout << "ProtectionProxy: Access denied for user " << user_ << "." << std::endl;
        }
    }

private:
    bool checkAccess() const {
        // 假设只有用户 "admin" 可以访问真实对象
        return user_ == "admin";
    }

    RealSubject real_subject_;
    std::string user_;
};

int main() {
    // 创建保护代理对象,指定用户为 "admin"
    ProtectionProxy proxy("admin");

    // 通过代理对象调用请求
    proxy.request();

    // 创建另一个保护代理对象,指定用户为 "guest"
    ProtectionProxy proxy2("guest");

    // 通过代理对象调用请求
    proxy2.request();

    return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。

然后我们定义了一个保护代理类 ProtectionProxy,它也实现了 Subject 接口。在 ProtectionProxy 中,我们实现了 request 方法,其中检查了用户的权限。如果权限通过,则使用真实主题对象来处理请求,否则拒绝访问。

在 main 函数中,我们创建了两个保护代理对象,一个指定用户为 "admin",另一个指定用户为 "guest"。只有第一个代理对象可以成功访问真实对象,因为只有用户 "admin" 才被授权访问。

缓存代理(Caching Proxy)用于缓存真实对象的结果,以减少对真实对象的重复调用,提高系统的性能。下面是一个简单的示例代码:

cpp
#include <iostream>
#include <unordered_map>

// 抽象主题接口
class Subject {
public:
    virtual std::string request(int key) const = 0;
};

// 具体主题类
class RealSubject : public Subject {
public:
    std::string request(int key) const override {
        std::cout << "RealSubject: Handling request for key " << key << "." << std::endl;
        // 模拟处理请求
        return "Result for key " + std::to_string(key);
    }
};

// 缓存代理类
class CachingProxy : public Subject {
public:
    std::string request(int key) const override {
        // 先尝试从缓存中获取结果
        auto it = cache_.find(key);
        if (it != cache_.end()) {
            std::cout << "CachingProxy: Returning cached result for key " << key << "." << std::endl;
            return it->second;
        }

        // 如果缓存中不存在,则调用真实主题对象处理请求,并缓存结果
        std::string result = real_subject_.request(key);
        cache_[key] = result;
        return result;
    }

private:
    RealSubject real_subject_;
    mutable std::unordered_map<int, std::string> cache_;
};

int main() {
    // 创建缓存代理对象
    CachingProxy proxy;

    // 第一次调用请求
    std::cout << proxy.request(1) << std::endl;

    // 第二次调用请求,应该从缓存中获取结果
    std::cout << proxy.request(1) << std::endl;

    // 第三次调用请求,使用不同的键,触发新的请求
    std::cout << proxy.request(2) << std::endl;

    return 0;
}
在这个示例中,我们定义了一个抽象主题类 Subject 和一个具体主题类 RealSubject,其功能是处理请求。

然后我们定义了一个缓存代理类 CachingProxy,它也实现了 Subject 接口。在 CachingProxy 中,我们实现了 request 方法,其中使用了一个 std::unordered_map 作为缓存,以存储已经处理过的请求结果。在处理请求时,先尝试从缓存中获取结果,如果缓存中不存在,则调用真实主题对象处理请求,并将结果缓存起来。

在 main 函数中,我们创建了一个缓存代理对象,并分别调用了几次请求方法,演示了缓存代理的工作原理。


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值