外观模式(c++实现)
外观模式
模式定义
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
模式动机
- 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
- 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
- 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
UML类图

源码实现
- hero.h
#ifndef HERO_H
#define HERO_H
#include <QDebug>
class Hero
{
public:
Hero(QString name):m_Name(name){}
~Hero(){}
inline void ZhongDan() { qDebug() << m_Name << " 中单";}
inline void DaYe() { qDebug() << m_Name << " 打野";}
inline void FuZhu() { qDebug() << m_Name << " 辅助";}
inline void FaYu() { qDebug() << m_Name << " 发育";}
inline void KangYa() { qDebug() << m_Name << " 抗压";}
protected:
QString m_Name;
};
class ZhenJi : public Hero
{
public:
ZhenJi():Hero("甄姬"){}
~ZhenJi(){}
};
class ZhaoYun : public Hero
{
public:
ZhaoYun():Hero("赵云"){}
~ZhaoYun(){}
};
class XiangXiang : public Hero
{
public:
XiangXiang():Hero("大小姐"){}
~XiangXiang(){}
};
class LianPo : public Hero
{
public:
LianPo():Hero("廉颇"){}
~LianPo(){}
};
class LvBu : public Hero
{
public:
LvBu():Hero("吕布"){}
~LvBu(){}
};
#endif // HERO_H
- facade.h
#ifndef FACADE_H
#define FACADE_H
/************************************
* @brief : 用外观模式封装几个不同的子系统,
* 子系统的操作统一放到外观模式的方法去
* 峡谷系统安排:
* 外观类:游戏不同的阵容组合
* 英雄类:不同的英雄,可以打不同的位置
* 外观类组合不同的英雄,得到一个胜率值
* @author : wzx
* @date : 2020-04-17
* @project : Facade
*************************************/
#include "hero.h"
class Facade
{
public:
Facade();
~Facade();
double LineUpA();
double LineUpB();
double LineUpC();
private:
XiangXiang* m_XX;
ZhaoYun* m_ZY;
LvBu* m_LB;
LianPo* m_LP;
ZhenJi* m_ZJ;
};
#endif // FACADE_H
- facade.cpp
#include "facade.h"
#define DELEOBJECT(x) if(x == nullptr) { delete x; x = nullptr;}
Facade::Facade()
{
m_XX = new XiangXiang();
m_ZY = new ZhaoYun();
m_LB = new LvBu();
m_LP = new LianPo();
m_ZJ = new ZhenJi();
}
Facade::~Facade()
{
DELEOBJECT(m_XX);
DELEOBJECT(m_ZY);
DELEOBJECT(m_LB);
DELEOBJECT(m_LP);
DELEOBJECT(m_ZJ);
}
double Facade::LineUpA()
{
m_XX->FaYu();
m_ZY->DaYe();
m_LB->KangYa();
m_LP->FuZhu();
m_ZJ->ZhongDan();
return 0.88;
}
double Facade::LineUpB()
{
m_XX->FaYu();
m_ZY->KangYa();
m_LB->DaYe();
m_LP->FuZhu();
m_ZJ->ZhongDan();
return 0.40;
}
double Facade::LineUpC()
{
m_XX->FaYu();
m_ZY->DaYe();
m_LB->ZhongDan();
m_LP->KangYa();
m_ZJ->FuZhu();
return 0.60;
}
- main.cpp
#include <QCoreApplication>
#include "facade.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Facade facade;
qDebug() << "胜率" << facade.LineUpA()*100 << "%" << endl;
qDebug() << "胜率" << facade.LineUpB()*100 << "%" << endl;
qDebug() << "胜率" << facade.LineUpB()*100 << "%" << endl;
return a.exec();
}
- 运行结果
"大小姐" 发育
"赵云" 打野
"吕布" 抗压
"廉颇" 辅助
"甄姬" 中单
胜率 88 %
"大小姐" 发育
"赵云" 抗压
"吕布" 打野
"廉颇" 辅助
"甄姬" 中单
胜率 40 %
"大小姐" 发育
"赵云" 抗压
"吕布" 打野
"廉颇" 辅助
"甄姬" 中单
胜率 40 %
优点
外观模式的优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
- 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
- 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
- 完美的体现了依赖倒转原则和迪米特法则
缺点
外观模式的缺点
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
参考《大话设计模式》和 https://design-patterns.readthedocs.io/zh_CN/latest/index.html
外观模式(c++实现)的更多相关文章
- 设计模式(八): 从“小弟”中来类比"外观模式"(Facade Pattern)
在此先容我拿“小弟”这个词来扯一下淡.什么是小弟呢,所谓小弟就是可以帮你做一些琐碎的事情,在此我们就拿“小弟”来类比“外观模式”.在上面一篇博文我们完整的介绍了“适配器模式”,接下来我们将要在这篇博客 ...
- 设计模式(十一)外观模式(Facade Pattern)
一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...
- 每天一个设计模式-2 外观模式(Facade)
每天一个设计模式-2 外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...
- 设计模式--外观模式Facade(结构型)
一.外观模式 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观模式定义了一个高层接口,让子系统更容易被使用. 二.UML图 三.例子 举个编译器的例子,假设编译一个程序需要经过四个步骤: ...
- Objective-C 外观模式--简单介绍和使用
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用. 在以下情况下可以考虑使用外观模式: (1)设计初期阶段,应该有意识的将不同层分 ...
- C#设计模式-外观模式
在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ”门面“模 ...
- C#设计模式系列:外观模式(Facade)
外观模式主要解决的问题是:当我们有多个类要处理时,往往要一个类一个类地区调用,没有复用性和扩展性.外观模式通过定义一个界面,把处理子类的过程封装成操作,主要就把用户从复杂的调用过程中解放出来. 1.外 ...
- 装饰模式 - Decorator 和 外观模式 - Facade
装饰模式 Decorator,不改变接口但动态给对象加入责任,所需功能按顺序串联起来控制,比生成子类灵活. 外观模式 Facade,让接口更简单.为子系统中的一组接口提供一个一致的界面. 参考:
- java设计模式之外观模式
外观模式概念 外观模式又称为门面模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个搞层次接口,使得这一个子系统更加容易使用.这一模式完美的体现了依赖倒转原则和迪米特法则的思想,所以是非常常 ...
- [Head First设计模式]生活中学设计模式——外观模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
随机推荐
- Gitblit无法查看单个文件解决方案
一个简单的解决方案是在reference.properties中设置: web.mountParameters = false 在这种情况下,您完全避免了该问题,因为项目名称,分支和文件名作为查询字符 ...
- C++ 深拷贝和浅拷贝详解
前言 在对象拷贝过程中,如果没有自定义拷贝构造函数,系统会提供一个缺省的拷贝构造函数,缺省的拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型成员变量,调用其相应类型的拷贝构造函数. 位拷贝( ...
- Spring MVC系列-(3) Bean的装配
3. 高级装配Bean 3.1 Bean的作用域 默认情况下,Spring中的bean都是以单例的形式存在的,无论注入多少次,每次注入的都是同一个实例. 考虑到某些bean可能是可变的,Spring定 ...
- python对目录下的文件进行 多条件排序
在进入正题之前,先介绍一下基础知识: 1.sort(),方法:就是对列表内容进行正向排序,直接在原列表进行修改,返回的是修改后的列表 lists =[1, 5, 10, 8, 6]lists.sort ...
- 单例模式和配置admin
单例模式和配置admin 单例模式的概念 单例模式主要目的是确保某一个类只有一个实例存在.比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信 ...
- beautifulsoup实现文章截取和脚本攻击
引子:现在我们所写的所有高大上,炫酷的网页,在数据库中是如何存储的呢?其实数据库中存储的所有高大上的文章都是存的html,然后我们平时看的写的都是由于编辑器的原因,在编辑器内部做了转换,所以我们可以直 ...
- Nginx | CentOS 8 安装Nginx详细教程
Nginx是一个web服务器也可以用来做负载均衡及反向代理使用, 目前使用最多的就是负载均衡,这篇文章主要介绍了centos8 安装 nginx Nginx是一种开源的高性能HTTP和反向代理服务器, ...
- 详解firewalld 和iptables
在RHEL7里有几种防火墙共存:firewalld.iptables.ebtables,默认是使用firewalld来管理netfilter子系统,不过底层调用的命令仍然是iptables等. fir ...
- Node/Python 工具搭建cmder和nrm
一.安装cmder cmder是windows下的一款终端工具,支持很多linux命令,用起来还是很爽的. 1.安装 http://cmder.net/ 直接在官网下载,解压即可. 2.cmder配置 ...
- Python第六章-函数02-函数的作用域
函数 三.作用域规则 有了函数之后,我们必须要面对一个作用域的问题. 比如:你现在访问一个变量,那么 python 解析器是怎么查找到这个变量,并读取到这个变量的值的呢? 依靠的就是作用域规则! 3. ...