《C++新经典设计模式》之第14章 代理模式

本文介绍了C++中的代理模式,包括远程代理、虚拟代理、保护代理、缓存代理和智能引用代理,通过示例展示了如何在实际编程中实现代理以控制对象访问、增加功能和优化性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《C++新经典设计模式》之第14章 代理模式

代理模式.cpp
#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <fstream>
using namespace std;

// 客户端和访问对象间引入代理对象(间接层),中介或桥梁
// 增加额外功能、约束或屏蔽复杂细节
// 为其他对象提供一种代理,以控制对这个对象的访问
// 3种角色
// Subject(抽象主题),定义接口
// Proxy(代理主题),内部包含真实主题的引用
// RealSubject(真实主题),代理主题所代表的真实主题

// 远程代理
// 虚拟代理
// 保护代理
// 缓存/缓冲代理
// 智能引用代理
// 写时复制优化代理

namespace ns1
{
    class WebAddr
    {
    public:
        virtual ~WebAddr() {}
        virtual void visit() = 0; // 访问网站
    };

    class WebAddr_Shopping : public WebAddr // 某购物网站
    {
    public: // 访问该购物网站,可能涉及到复杂的网络通信
        void visit() override { cout << "visit WebAddr_Shopping!" << endl; }
    };

    class WebAddr_Video : public WebAddr // 某视频网站
    {
    public: // 访问该视频网站,可能涉及到复杂的网络通信
        void visit() override { cout << "visit WebAddr_Video!" << endl; }
    };

    class WebAddrProxy : public WebAddr // 网站代理类
    {
        shared_ptr<WebAddr> mp_webaddr; // 代表要访问的具体网站
    public:                             // 引入的目的是传递进来要访问的具体网站
        WebAddrProxy(const shared_ptr<WebAddr> &pwebaddr) : mp_webaddr(pwebaddr) {}

    public:
        void visit() override
        {
            // 在这里进行访问的合法性检查、日志记录或者流量限制......
            if (mp_webaddr != nullptr)
                mp_webaddr->visit();
            // 在这里可以进行针对返回数据的过滤......
        }
    };

    class WebAddr_Shopping_Proxy : public WebAddr // 专门针对某购物网站WebAddr_Shopping的代理
    {
    public:
        void visit() override
        {
            // 在这里进行访问的合法性检查、日志记录或者流量限制......
            shared_ptr<WebAddr> p_webaddr(new WebAddr_Shopping());
            p_webaddr->visit();
            // 在这里可以进行针对返回数据的过滤......
        }
    };
}

namespace ns2
{
    static vector<string> g_fileItemList;

    class ReadInfo // 抽象主题
    {
    public:
        virtual ~ReadInfo() {}
        virtual void read() = 0;
    };

    class ReadInfoFromFile : public ReadInfo // 真实主题
    {
    public:
        void read() override
        {
            ifstream fin(".vscode/settings.json"); // 文件中读取信息
            if (!fin)
            {
                cout << "failure" << endl;
                return;
            }

            g_fileItemList.clear();
            string linebuf;
            while (getline(fin, linebuf)) // 系统函数,从文件中逐行读入内容
            {
                if (!linebuf.empty())                  // 读入的不是空行
                    g_fileItemList.push_back(linebuf); // 将文件中的每一行都保存到vector容器中
            }
            fin.close(); // 关闭文件输入流
        }
    };

    class ReadInfoProxy : public ReadInfo // 代理主题
    {
        bool m_loaded = false; // false表示还没有从文件中读出数据到内存
    public:
        void read() override
        {
            if (!m_loaded)
            {
                // 没有从文件中载入信息,则载入
                m_loaded = true; // 标记信息已经从文件中被载入进来,这样下次再获取这些数据时就不需要再去读文件了

                shared_ptr<ReadInfo> rf(new ReadInfoFromFile());
                rf->read(); // 将文件中的数据读入全局容器g_fileItemList中

                cout << "read from file: " << endl;
            }
            else
            {
                cout << "read from cache: " << endl;
            }

            // 现在数据一定在g_fileItemList中,开始显示
            for (auto iter = g_fileItemList.cbegin(); iter != g_fileItemList.cend(); ++iter)
                cout << *iter << endl;
        }
    };
}

int main()
{
#if 0
    using namespace ns1;

    shared_ptr<WebAddr> wba1(new WebAddr_Shopping());
    wba1->visit(); // 访问该购物网站

    shared_ptr<WebAddr> wba2(new WebAddr_Video());
    wba2->visit(); // 访问该视频网站
#endif

#if 0
    using namespace ns1;

    shared_ptr<WebAddr> wba1(new WebAddr_Shopping());
    shared_ptr<WebAddr> wbaproxy1(new WebAddrProxy(wba1));
    wbaproxy1->visit(); // 通过代理去访问WebAddr_Shopping购物网站

    shared_ptr<WebAddr> wba2(new WebAddr_Video());
    shared_ptr<WebAddr> wbaproxy2(new WebAddrProxy(wba2));
    wbaproxy2->visit(); // 通过代理去访问WebAddr_Video视频网站
#endif

#if 0
    using namespace ns1;
    shared_ptr<WebAddr> wbasproxy(new WebAddr_Shopping_Proxy());
    wbasproxy->visit(); // 访问的实际是某购物网站
#endif

#if 1
    using namespace ns2;

    shared_ptr<ReadInfo> preadinfoproxy(new ReadInfoProxy());
    preadinfoproxy->read(); // 第一次调用read是借助代理使用真实的主题到文件中拿数据
    preadinfoproxy->read(); // 后续调用read都是直接从缓存中拿数据
    preadinfoproxy->read(); // 从缓存中拿数据
#endif

    return 0;
}
### PyCharm 打开文件显示全的解决方案 当遇到PyCharm打开文件显示全的情况时,可以尝试以下几种方法来解决问题。 #### 方法一:清理缓存并重启IDE 有时IDE内部缓存可能导致文件加载异常。通过清除缓存再启动程序能够有效改善此状况。具体操作路径为`File -> Invalidate Caches / Restart...`,之后按照提示完成相应动作即可[^1]。 #### 方法二:调整编辑器字体设置 如果是因为字体原因造成的内容显示问题,则可以通过修改编辑区内的文字样式来进行修复。进入`Settings/Preferences | Editor | Font`选项卡内更改合适的字号大小以及启用抗锯齿功能等参数配置[^2]。 #### 方法三:检查项目结构配置 对于某些特定场景下的源码视图缺失现象,可能是由于当前工作空间未能正确识别全部模块所引起。此时应该核查Project Structure的Content Roots设定项是否涵盖了整个工程根目录;必要时可手动添加遗漏部分,并保存变更生效[^3]。 ```python # 示例代码用于展示如何获取当前项目的根路径,在实际应用中可根据需求调用该函数辅助排查问题 import os def get_project_root(): current_file = os.path.abspath(__file__) project_dir = os.path.dirname(current_file) while not os.path.exists(os.path.join(project_dir, '.idea')): parent_dir = os.path.dirname(project_dir) if parent_dir == project_dir: break project_dir = parent_dir return project_dir print(f"Current Project Root Directory is {get_project_root()}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值