通过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语言实现点菜系统

    C语言实现点菜系统 本攻略将介绍如何使用C语言实现一个简单的点菜系统。在这个系统中,顾客可以浏览菜单,选择自己的菜品并计算价格。系统则会输出选择的菜品及总价。 基本思路 定义菜单。菜单的定义可以采用数组的方式实现,每个元素代表一道菜品,包括名称和价格。 展示菜单。通过循环遍历数组,输出所有菜品名称及价格。 用户选择菜品。通过让用户输入菜品的编号,实现选择菜品…

    C 2023年5月23日
    00
  • 如何修复Win11/10坏图像错误0xc0000020?

    当Win11/10出现坏图像错误0xc0000020时,可能是由于您的显卡驱动程序损坏或未正确安装。下面是完整的修复步骤: 步骤1:重新安装显卡驱动程序 1.打开设备管理器,展开“显示适配器”选项。 2.右击显示适配器,选择“卸载设备”。 3.下载并安装最新版本的显卡驱动程序,可以在厂商官网下载。 4.安装完成后,重启计算机,检查错误是否消失。 步骤2:运行…

    C 2023年5月23日
    00
  • C语言应用领域分析

    C语言应用领域分析攻略 1. 概述 C语言是一门功能强大的编程语言,被广泛应用于各个领域。在进行C语言应用领域分析之前,我们需要了解一下C语言的特点和优势。 C语言是一门高效的编程语言,能够快速地处理大量数据。 C语言的兼容性非常好,可以运行在各种平台上,包括Windows、Mac OS、Linux等。 C语言具有强大的功能库,涵盖了计算机科学中的各种领域,…

    C 2023年5月23日
    00
  • C语言中.与->的用法介绍

    下面是C语言中.与->的用法介绍的完整攻略。 什么是.和-> .和->都是C语言中的运算符,用来访问结构体中的成员。 .运算符是用来访问结构体变量中的成员的,而->运算符是用来访问结构体指针变量(或者类指针变量)中的成员的。 .的用法 .运算符基本语法如下所示: 结构体变量名.成员名; 其中,结构体变量名是结构体类型的变量名,成员名是…

    C 2023年5月22日
    00
  • C语言打印正方形实例代码

    请注意阅读以下内容: 打印正方形实例代码 在C语言中,使用循环语句可以轻松打印出正方形图形。下面是一份简单的C代码示例: #include <stdio.h> int main() { int i, j, num; printf("请输入要打印正方形的边长(1-20):"); scanf("%d", &am…

    C 2023年5月24日
    00
  • 如何解决电脑提示应用程序正常初始化(0xc0000142)失败的问题

    问题描述: 在电脑打开某些应用程序时,会出现类似于以下提示的错误信息: “应用程序无法正常启动(0xc0000142)。单击[确定]关闭应用程序。” 这种错误表示该应用程序无法正常初始化,有可能是因为它受到了病毒、间谍软件、不完整的应用程序更新或者系统中的故障等因素的影响。 针对这种错误,以下是一些可以尝试的解决方案: 1. 运行挂起的服务 如果该错误是因为…

    C 2023年5月23日
    00
  • C语言实现考试报名管理系统

    C语言实现考试报名管理系统攻略 系统介绍: 本系统使用C语言编写,实现了考试报名管理系统,可以方便地管理考试的报名、查询与统计工作。 系统功能: 学生信息管理:系统中可以管理考生信息,包括学生姓名、学号、报考考试、成绩等信息。 考试报名:考生可以通过登录系统进行报名。 考试查询:考生和管理员根据个人信息可以查询自己或其他考生的成绩,并且管理员可以查看全体考生…

    C 2023年5月23日
    00
  • 全面了解java中的异常处理

    全面了解Java中的异常处理 Java中的异常处理是一种机制,可以让我们在程序中捕获并处理可能会出现的异常。在Java中,异常分为受检异常和非受检异常。受检异常必须在代码中显式处理,而非受检异常则不需要。Java中还提供了一组异常处理机制,包括try-catch-finally语句、throws语句和finally语句等。 受检异常和非受检异常 Java中的…

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