您现在的位置是:首页 > 正文

7.外观模式C++用法示例

2024-02-29 16:23:23阅读 1

一.外观模式

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个简单的接口,隐藏了一个或多个复杂的子系统的复杂性,并使这些子系统更容易使用。

1.原理

外观模式的实现原理是将客户端与子系统解耦,使客户端不需要了解子系统内部结构和实现细节,只需与外观类交互即可完成相应操作。外观类将客户端的请求委托给子系统中的相应组件来处理,从而实现对子系统的封装。

2.特点

  1. 简化客户端与子系统之间的交互。客户端只需要通过外观类来访问子系统,而不需要了解子系统的内部结构和实现细节。
  2. 降低客户端与子系统之间的耦合度。外观类充当了客户端与子系统之间的中介,使得它们之间的依赖关系变得简单明了。
  3. 提高子系统的可维护性。由于客户端只能通过外观类来访问子系统,因此可以更容易地对子系统进行修改和维护,而不会对客户端造成影响。
  4. 隐藏子系统的复杂性。外观类封装了子系统的复杂性,使得客户端无需了解子系统的内部实现细节。
  5. 可以对子系统进行进一步封装。外观类可以进一步封装子系统,以提供更简单、更易用的接口给客户端使用。

3.外观模式与装饰器模式的异同

  • 相同点

1.都是结构型设计模式,关注的是对象之间的组合方式。
2.都可以在不改变原有对象结构的基础上,为对象添加新的行为。
3.都能够提高系统的灵活性和可扩展性,降低了系统的耦合度。

  • 不同点

1.目的不同:外观模式的目的是简化客户端与子系统之间的交互,隐藏子系统的复杂性;而装饰器模式的目的是在不改变原有对象结构的基础上,动态地为对象添加新的功能。
2.装饰对象的方式不同:外观模式中定义一个外观类,它封装了子系统的复杂性,并提供了一个简单的接口,以方便客户端访问子系统;在装饰器模式中使用了一个装饰器类,它包装了一个具体组件(即被装饰对象),并在运行时动态地为其添加新的行为。
3.关注点不同:外观模式关注的是对整个子系统的封装,以简化客户端的操作;而装饰器模式关注的是对单个对象的功能扩展,以增强其功能。
4.对原有类的影响不同:外观模式对原有子系统的代码没有任何影响,而装饰器模式则需要在原有类的基础上进行修改或添加新的代码。
5.调用方式不同:在外观模式中,客户端通过调用外观类的方法来访问子系统的功能;而在装饰器模式中,客户端通过调用装饰器对象的方法来访问被装饰对象的功能。

4.应用场景

  1. 封装复杂的子系统:外观模式常常用于封装复杂的子系统,例如操作系统的API接口、数据库的访问接口等。外观模式将这些复杂的子系统封装在一个外观类中,为客户端提供一个简单的接口,从而降低了客户端的开发难度。
  2. 简化接口:外观模式可以为客户端提供一个简单易用的接口,使得客户端能够更加方便地使用系统的功能。例如,一个多媒体播放器可能会使用外观模式来封装底层的音频、视频解码器,为客户端提供一个统一的播放接口。
  3. 实现系统解耦:外观模式可以将客户端与子系统之间的耦合度降到最低,从而提高系统的可维护性和可扩展性。例如,当需要更换底层的子系统时,只需要修改外观类即可,而不会影响客户端代码。
  4. 提高系统的性能:在一些性能要求较高的场景中,外观模式可以通过封装多个子系统的接口,实现一次性调用多个接口的功能,从而提高系统的性能。

C++程序示例

#include <iostream>
#include <string>
#include <vector>

// 子系统:账户
class AccountSystem {
public:
    void createAccount(const std::string& name, const std::string& password) {
        std::cout << "create account: " << name << std::endl;
    }

    void login(const std::string& name, const std::string& password) {
        std::cout << "login: " << name << std::endl;
    }

    void logout(const std::string& name) {
        std::cout << "logout: " << name << std::endl;
    }
};

// 子系统:存款
class DepositSystem {
public:
    void deposit(const std::string& name, double amount) {
        std::cout << "deposit " << amount << " to account " << name << std::endl;
    }

    void withdraw(const std::string& name, double amount) {
        std::cout << "withdraw " << amount << " from account " << name << std::endl;
    }
};

// 子系统:转账
class TransferSystem {
public:
    void transfer(const std::string& from, const std::string& to, double amount) {
        std::cout << "transfer " << amount << " from account " << from << " to account " << to << std::endl;
    }
};

// 外观类:银行系统
class BankSystem {
public:
    BankSystem() {
        accountSystem = new AccountSystem();
        depositSystem = new DepositSystem();
        transferSystem = new TransferSystem();
    }

    ~BankSystem() {
        delete accountSystem;
        delete depositSystem;
        delete transferSystem;
    }

    // 创建账户
    void createAccount(const std::string& name, const std::string& password) {
        accountSystem->createAccount(name, password);
    }

    // 登录
    void login(const std::string& name, const std::string& password) {
        accountSystem->login(name, password);
    }

    // 存款
    void deposit(const std::string& name, double amount) {
        depositSystem->deposit(name, amount);
    }

    // 取款
    void withdraw(const std::string& name, double amount) {
        depositSystem->withdraw(name, amount);
    }

    // 转账
    void transfer(const std::string& from, const std::string& to, double amount) {
        transferSystem->transfer(from, to, amount);
    }

private:
    AccountSystem* accountSystem;
    DepositSystem* depositSystem;
    TransferSystem* transferSystem;
};

// 客户端调用
int main() {
    BankSystem bank;
    bank.createAccount("Alice", "123456");
    bank.login("Alice", "123456");
    bank.deposit("Alice", 1000);
    bank.transfer("Alice", "Bob", 500);
    bank.withdraw("Alice", 200);
    return 0;
}

在这里插入图片描述

网站文章

  • 【fabric】测上链与查询时间

    【fabric】测上链与查询时间

    今天又不行了所以又百度了一下https://blog.csdn.net/lakersssss24/article/details/118369300用这个博主的方法,解决“Error: error g...

    2024-02-29 16:22:55
  • JAVA多线程的初级认识2-线程安全性

    JAVA多线程的初级认识2-线程安全性

    线程安全性是一个麻烦的难题~从而造成了多线程代码的难写的重要原因。那就从物理和JMM两个层面去了解安全性是如何出现问题的。 物理层面 由于计算机设备的计算能力不均,大致可分为,IO设备 < 内存 < CPU,由于计算能力相差太大。导致很多的地方需要用到缓存,大致的缓存模型如下:一级缓存L1:包含数据缓存和指令缓存二级缓存L2: 各个CPU私有三级缓存L3:...

    2024-02-29 16:22:47
  • C语言(十七)链表

    一、算法        通俗定义:            解题的方法和步骤        狭义定义:            对存储数据的操作            对不同的存储结构,要完成某一个功能所执行的操作时不一样的            比如:               要输出数组中所有的元素的操作和               要输出数组中所有元...

    2024-02-29 16:22:32
  • AI 时代,程序员无需焦虑

    AI 时代,程序员无需焦虑

    当一个问题被明确并拆解到软件项目维度的时候,面对确定的任务、清晰的目标、合理的架构,可以解决问题的人就非常多了,AI 自然也才有用武之地。大型软件系统,本身往往具有较高的复杂度。如果把你放到陌生的小区...

    2024-02-29 16:22:24
  • windows10文件服务器,windows10文件服务器

    windows10文件服务器,windows10文件服务器

    windows10文件服务器 内容精选换一换华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档,帮助您快速上手使用华为云服务。本文以云...

    2024-02-29 16:21:56
  • Linux常用150个命令

    常用Linux操作做指令

    2024-02-29 16:21:48
  • python的__name__属性详解

    python的__name__属性详解

    有关文件导入: 一个独立的python文件就是一个模块 在导入文件时,文件中 所有没有任何缩进的代码都会被执行一遍 在实际开发中,开发人员通常会在模块下方增加一些测试代码,测试代码是仅在模块内使用,而被导入到其他文件中不需要执行 这里就需要知__name__属性 __name__属性可以做到,测试模块的代码只在测试情况下被运行,而在被导入时不会被执行 __name__时python的一个内置...

    2024-02-29 16:21:41
  • 一篇文章让你弄懂二分查找

    一篇文章让你弄懂二分查找

    首先,我们要聊一下什么是二分查找,二分查找只适用于有序表,举个例子,一个元素1-10的数组,我要你找到元素7所在的位置,通过我们人眼观察,你可能一下子就可以找到。此时,我们要找的元素7比mid下标所指...

    2024-02-29 16:21:12
  • 第一章 动态网页基础

    第一章 动态网页基础

    本章简介     通过学习的JavaSE、Web前端等方面的技术,从本章开始,将结合之前所学内容,逐步接触用用的Web系统开发。本章将从动态页面和静态页面的区别说起,介绍Web应用系统的工作原理。大家...

    2024-02-29 16:20:58
  • 朝戈《敏感者》

    朝戈《敏感者》

     朝戈《敏感者》  1986年,朝戈回到他求学四年的母校,这次,他是以一名教师的身份进入中央美术学院的。 20世纪90年代在不知不觉中悄然来临了。美术学院的高墙虽然挡住了市井的喧闹,但激烈的社会变革气息透过墙角的隙缝吹进了校园。这种躁动的情绪影响了朝戈。 中央美术学院教授 朝戈:这个时代

    2024-02-29 16:20:30