C++设计模式(代理模式)

1. 电话虫

在海贼中,有一种神奇的通信工具叫做电话虫(Den Den Mushi),外形如蜗牛,身上带有斑点或条纹或通体纯色,壳顶上有对讲机或按键,不接通时会睡觉,接通时会惊醒,并发出"波噜波噜"的声音,在通话时电话虫的嘴巴会如同讲话人的嘴巴一样动,也有人的感情听得懂人类说话,工作原理是将人的声音转化为电话虫的声音进行长距离传接,经作者尾田荣一郎在SBS上证实这是自然生长的一种虫。

如果拥有了属于对方的电话虫,不论彼此相隔有多远都可以进行时时通信,通过电话虫除了可以听到对方的声音,还能看到对方的表情,妥妥的一个代理人。在设计模式中有一种模式叫做代理模式,代理模式和电话虫差不多,都是为其他对象提供一种代理,以控制对这个对象的访问。

生活中关于代理的例子也有很多,比如:

  • 通过信用卡、微信、支付宝等代替现金支付
  • 开发一套对接数据库服务器的接口并提供给客户使用,用于提高服务器的访问效率
  • 跑腿小哥代替大聪明给异地的女盆友送花。
  • 通过VPN架梯子访问外网。

2. 解构电话虫

如果我们想要用代理模式来描述一下电话虫的行为,里边有如下几个细节:

  1. 说话的人是一个对象,电话虫也是一个对象,电话虫模拟的是说话的人
  2. 说话的人和电话虫有相同的行为,所以需要为二者提供一个抽象类
  3. 电话虫是在为说话的人办事,所以电话虫和说话人应该有关联关系。

根据上面的描述,先把对应的UML类图画一下:

由于电话虫类和讲话者类不是部分与整体的关系,所以这二者的关系是关联关系。

3. 通话

根据上面的UML类图,先把通话的抽象类定义出来:

cpp 复制代码
// 抽象通信类
class Communication
{
public:
    virtual void communicate() = 0; // 通话
    virtual ~Communication() {}
};

然后在根据这个抽象类,派生出两个子类:讲话者类和电话虫类:

cpp 复制代码
// 讲话的人
class Speaker : public Communication
{
public:
    void communicate() override
    {
        cout << "开始说话..." << endl;
        cout << "通话时发生了一些列的表情变化..." << endl;
    }
};

// 电话虫
class DenDenMushi : public Communication
{
public:
    DenDenMushi()
    {
        m_isStart = true;
        m_speaker = new Speaker;
    }
    ~DenDenMushi()
    {
        if (m_speaker != nullptr)
        {
            delete m_speaker;
        }
    }
    // 判断是否已经开始通话了
    bool isStart()
    {
        return m_isStart;
    }
    void communicate() override
    {
        if (isStart())
        {
            // 得到通话者语言和表情信息, 并加以模仿
            cout << "电话虫开始实时模仿通话者的语言和表情..." << endl;
            m_speaker->communicate();
       }
    }
private:
    bool m_isStart = false;
    Speaker* m_speaker = nullptr;
};

海贼官方给出的电话虫的名字叫做DenDenMushi,所以电话虫类也以此命名。

在代理类也就是电话虫类中,一般都会判断是否允许代理(对应示例程序中的isStart(),表示通话对否开始了),如果允许则通过被代理的对象m_speaker,调用它的操作函数communicate() 。

最后是测试代码:

cpp 复制代码
int main()
{
    // 直接交流
    Communication* comm = new Speaker;
    comm->communicate();
    delete comm;
    cout << "===================================" << endl;
    // 使用电话虫
    comm = new DenDenMushi;
    comm->communicate();
    delete comm;

    return 0;
}

上面的测试程序中一共使用了两种方式进行通信,第二种使用的是代理模式,我们可以在代理类中有效的管理被代理的对象的工作的时机,但是并没有改变被代理的对象的行为。

原文链接: https://subingwen.cn/design-patterns/proxy/#3-通话

相关推荐
励志的小陈2 小时前
数据结构--二叉树知识讲解
数据结构
CPUOS20103 小时前
嵌入式C语言高级编程之MVC设计模式
c语言·设计模式·mvc
自信150413057593 小时前
重生之从0开始学习c++之模板初级
c++·学习
leobertlan3 小时前
好玩系列:用20元实现快乐保存器
android·人工智能·算法
青梅橘子皮3 小时前
C语言---指针的应用以及一些面试题
c语言·开发语言·算法
笨笨饿3 小时前
#58_万能函数的构造方法:ReLU函数
数据结构·人工智能·stm32·单片机·硬件工程·学习方法
浅时光_c3 小时前
3 shell脚本编程
linux·开发语言·bash
历程里程碑3 小时前
2. Git版本回退全攻略:轻松掌握代码时光机
大数据·c++·git·elasticsearch·搜索引擎·github·全文检索
极客智造4 小时前
深度解析 C++ 类继承与多态:面向对象编程的核心
c++
Lucis__4 小时前
一文读懂TCP通信机制:基于相关API构建可靠性连接
linux·网络·tcp/ip