通过C++程序示例理解设计模式中的外观模式

一、设计模式中的外观模式

  • 定义: 外观模式(Facade Pattern)提供了一个统一的接口,用来访问子系统中的一群接口。其目的是简化子系统的使用,消除客户端和子系统之间的耦合,让子系统内部的模块更容易维护和扩展。
  • 要点: 
    • 外观模式不暴露子系统的内部细节,仅暴露一个应用程序所需进行的操作。
    • 外观类是客户端与子系统之前的第一层封装,对于多个子系统,客户端可以通过外观类的公共接口依次访问它们。
    • 外观模式旨在降低系统的复杂度,其最大的优点就是能够让客户端和子系统之间的耦合度降到最低。

二、C++程序示例说明

1. 示例一

我们来看一个简单的外观模式示例,假设我们有一个计算器程序,里面有加减乘除四个功能,每个功能都需要调用一堆子系统类的方法才能完成,代码如下:

#include <iostream>

class Adder {
public:
    int add(int a, int b) {
        return a + b;
    }
};

class Subtractor {
public:
    int subtract(int a, int b) {
        return a - b;
    }
};

class Multiplier {
public:
    int multiply(int a, int b) {
        return a * b;
    }
};

class Divider {
public:
    int divide(int a, int b) {
        if (b == 0) {
            throw std::exception("Divided by zero!");
        }
        return a / b;
    }
};

class Calculator {
public:
    Calculator() : adder_(), subtractor_(), multiplier_(), divider_() {}

    int add(int a, int b) {
        return adder_.add(a, b);
    }

    int subtract(int a, int b) {
        return subtractor_.subtract(a, b);
    }

    int multiply(int a, int b) {
        return multiplier_.multiply(a, b);
    }

    int divide(int a, int b) {
        return divider_.divide(a, b);
    }

private:
    Adder adder_;
    Subtractor subtractor_;
    Multiplier multiplier_;
    Divider divider_;
};

int main() {
    Calculator calculator;
    std::cout << calculator.add(1, 2) << std::endl;
    std::cout << calculator.subtract(1, 2) << std::endl;
    std::cout << calculator.multiply(1, 2) << std::endl;
    std::cout << calculator.divide(1, 2) << std::endl;
    return 0;
}

上面这段代码中,四个计算功能分别实现在Adder、Subtractor、Multiplier和Divider类中,而这四个类又组成了Calculator类,作为一个子系统。客户端必须要知道这些类的存在,并且才能使用它们提供的计算功能。这对于客户端来说会很麻烦,因为客户端需要知道子系统内部的实现。

所以,我们可以引入外观模式来简化客户端和子系统之间的交互。我们添加一个新的类CalculatorFacade,把四个计算功能封装成了一个接口,客户端只需要调用这一个接口就可以完成各种计算,如下所示:

#include <iostream>

class Adder {
public:
    int add(int a, int b) {
        return a + b;
    }
};

class Subtractor {
public:
    int subtract(int a, int b) {
        return a - b;
    }
};

class Multiplier {
public:
    int multiply(int a, int b) {
        return a * b;
    }
};

class Divider {
public:
    int divide(int a, int b) {
        if (b == 0) {
            throw std::exception("Divided by zero!");
        }
        return a / b;
    }
};

class CalculatorFacade {
public:
    CalculatorFacade() : adder_(), subtractor_(), multiplier_(), divider_() {}

    int add(int a, int b) {
        return adder_.add(a, b);
    }

    int subtract(int a, int b) {
        return subtractor_.subtract(a, b);
    }

    int multiply(int a, int b) {
        return multiplier_.multiply(a, b);
    }

    int divide(int a, int b) {
        return divider_.divide(a, b);
    }

private:
    Adder adder_;
    Subtractor subtractor_;
    Multiplier multiplier_;
    Divider divider_;
};

int main() {
    CalculatorFacade calc;
    std::cout << calc.add(1, 2) << std::endl;
    std::cout << calc.subtract(1, 2) << std::endl;
    std::cout << calc.multiply(1, 2) << std::endl;
    std::cout << calc.divide(1, 2) << std::endl;
    return 0;
}

这里引入了CalculatorFacade类,作为客户端和子系统之间的交互层,把四个计算功能封装成了一个接口,客户端只需要和这一个类打交道就可以了,这样客户端和子系统之间的耦合度就降低了。

2. 示例二

再看一下一个更复杂的例子,假设我们有一个情景处理系统,要求实现一个包含多个子系统的日程管理系统。日程管理系统功能复杂,包含了提醒、加密、存储等多个模块,下面我们来看看如何使用外观模式简化这个系统。

首先我们定义了三个子系统类Reminder、Encrypter和Storage,代码如下:

#include <iostream>
#include <string>

class Reminder {
public:
    void remind(const std::string& action) {
        std::cout << "Reminder: " << action << std::endl;
    }
};

class Encrypter {
public:
    std::string encrypt(const std::string& data) {
        std::string result = data;
        std::cout << "Encrypter: " << result << std::endl;
        return result;
    }
};

class Storage {
public:
    void store(const std::string& data) {
        std::cout << "Storage: " << data << std::endl;
    }
};

这三个类分别实现了提醒、加密和存储功能。然后我们定义了一个类ScheduleManagerFacade,由于项目中要经常访问这三个子系统,所以这个类就成为了他们的管理者,代码如下:

#include <iostream>
#include <string>

class Reminder {
public:
    void remind(const std::string& action) {
        std::cout << "Reminder: " << action << std::endl;
    }
};

class Encrypter {
public:
    std::string encrypt(const std::string& data) {
        std::string result = data;
        std::cout << "Encrypter: " << result << std::endl;
        return result;
    }
};

class Storage {
public:
    void store(const std::string& data) {
        std::cout << "Storage: " << data << std::endl;
    }
};

class ScheduleManagerFacade {
public:
    ScheduleManagerFacade() : reminder_(), encrypter_(), storage_() {}

    void createSchedule(const std::string& data) {
        reminder_.remind("Create schedule.");
        std::string encrypted_data = encrypter_.encrypt(data);
        storage_.store(encrypted_data);
    }

    void updateSchedule(const std::string& data) {
        reminder_.remind("Update schedule.");
        std::string encrypted_data = encrypter_.encrypt(data);
        storage_.store(encrypted_data);
    }

    void deleteSchedule(const std::string& data) {
        reminder_.remind("Delete schedule.");
        std::string encrypted_data = encrypter_.encrypt(data);
        storage_.store(encrypted_data);
    }

    void viewSchedule(const std::string& data) {
        reminder_.remind("View schedule.");
        std::string encrypted_data = encrypter_.encrypt(data);
        storage_.store(encrypted_data);
    }

private:
    Reminder reminder_;
    Encrypter encrypter_;
    Storage storage_;
};

int main() {
    ScheduleManagerFacade scheduleManagerFacade;
    scheduleManagerFacade.createSchedule("This is a new schedule.");
    scheduleManagerFacade.updateSchedule("This schedule has been updated.");
    scheduleManagerFacade.deleteSchedule("This schedule has been deleted.");
    scheduleManagerFacade.viewSchedule("This schedule is view only.");
    return 0;
}

上面这段代码中,我们首先定义了Reminder、Encrypter和Storage三个子系统类,然后定义了一个ScheduleManagerFacade类作为外观类,客户端只需要和这个类打交道就可以了。ScheduleManagerFacade的每个成员函数都封装了子系统的实现细节,对外提供了统一的接口,可以方便地对日程进行创建、更新、删除和查看操作,不必去理解复杂的子系统实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通过C++程序示例理解设计模式中的外观模式 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • 在C++中加载TorchScript模型的方法

    在C++中加载TorchScript模型的方法 如果我们想要在C++中加载TorchScript模型(.pt或.pkl文件),则需要使用到libtorch库和TorchScript API。下面是加载模型的完整攻略: 下载libtorch库 在pytorch官网下载适合自己操作系统的libtorch库,解压后即可得到所需的头文件和库文件。 编写加载模型的代码…

    C 2023年5月23日
    00
  • 首款医学智能手环c+手环使用图文教程

    首款医学智能手环c+手环使用图文教程 什么是首款医学智能手环c+ 首款医学智能手环c+是一款能够监测用户健康状况的智能手环,它能够测量用户的心率、血氧、血压等多项指标,同时还支持日常步数、距离、卡路里消耗等数据的统计。手环还具有防丢功能,支持闹钟提醒、来电提醒、信息提醒等功能。 如何使用首款医学智能手环c+ 以下是手环使用流程的详细说明: 第一步:购买手环并…

    C 2023年5月22日
    00
  • C语言 动态内存分配的详解及实例

    C语言 动态内存分配的详解及示例 什么是动态内存分配 在编程中,有时我们需要根据实际情况动态地分配内存空间,而不是在编写时就预先分配好。这种内存分配方式被称为动态内存分配。动态内存分配可以避免预分配内存的浪费,同时还可以根据需要扩充内存。 C语言中提供了四个用于动态内存分配的库函数,分别是 malloc、calloc、realloc 和 free。 mall…

    C 2023年5月23日
    00
  • C语言实现客房管理系统

    C语言实现客房管理系统的完整攻略包含以下几个步骤: 设计数据结构和功能模块 首先需要设计客房管理系统的数据结构和功能模块。根据系统需要,可以设计出以下数据结构: Room:客房信息,包括客房号、类型、价格、当前状态(已入住或未入住)等。 Order:订单信息,包括客房号、入住时间、退房时间、客人姓名等。 根据这些数据结构,可以设计出以下功能模块: Check…

    C 2023年5月23日
    00
  • C语言 枚举类型(Enum)详解及示例代码

    那我来详细讲解一下“C语言 枚举类型(Enum)详解及示例代码”。 什么是枚举类型? 枚举类型是C语言中的一种基本数据类型,它是一组预定的常量的集合,在某些情况下可以用于替代常量。 枚举类型采用关键字enum定义,格式如下: enum 枚举名{ 枚举常量1, 枚举常量2, …… }; 其中,枚举常量默认从0开始,依次递增1,也可以手动指定初值。 枚举类型的应…

    C 2023年5月24日
    00
  • docker如何对已经启动的容器添加目录映射(挂载目录)

    对已经启动的容器添加目录映射(挂载目录)是一项常见的操作。Docker 提供了docker container update命令来实现这个功能。以下是具体的步骤: 查看容器ID 使用docker ps命令可以查看已经启动的容器列表,找到需要挂载目录的容器并记住其容器ID。例如,我们找到容器名为web的ID为52a5af67b207。 $ docker ps …

    C 2023年5月23日
    00
  • 华硕x550c笔记本电脑很卡怎么拆机清灰?

    针对“华硕x550c笔记本电脑很卡怎么拆机清灰?”这个问题,我提供以下攻略: 1. 准备材料 在拆机清灰之前,我们需要准备以下工具和材料: 气罐喷雾器、无尘布 螺丝刀 清灰软刷或者毛刷 硅脂(可选) 2. 拆机 首先,将电脑关闭,并断开电源线和所有外设。 将电脑背面的电池拆掉。如果是固态硬盘版本,需要拆下固态硬盘。 用螺丝刀卸下电脑底部的螺丝。不同型号的笔记…

    C 2023年5月22日
    00
  • 浅谈VC++中的内联

    针对“浅谈VC++中的内联”的问题,我为您提供如下攻略。 什么是内联函数? 内联函数是在编译器编译程序的时候,程序员要求编译器将函数直接将函数中的代码插入到函数调用的位置,而不是正常的调用函数的方式。因此,内联函数的执行效率较高,但会增加程序代码的大小。在C++中,使用关键字inline来定义内联函数。 如何在VC++中定义内联函数? 在VC++中,通常使用…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部