外观模式(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设计模式]山西面馆中的设计模式— ...
随机推荐
- 一步一步学习S-MSCKF(一)连续时间IMU误差状态运动模型
1 IMU真实状态运动模型 状态向量: \(x_{I}=\left[{{_{G}^{I}{q(t)}}^{T},{b_{g}(t)}^{T},{^{G}v_{I}(t)}^{T},{b_{a}(t)} ...
- JMeter报错:Address already in use : connect
Address already in use : connect的解决办法: 修改操作系统注册表1.打开注册表:regedit2.找到HKEY_LOCAL_MACHINE\SYSTEM\Current ...
- alsa-lib及alsa-utils成功移植(转载)
准备工作 alsa-lib版本:alsa-lib-1.0.23.tar.bz2 alsa-util版本:alsa-utils-1.0.23.tar.bz2 其他版本的alsa-lib和alsa-uti ...
- vue cli3配置开发环境、测试环境、生产(线上)环境
cli3创建vue项目是精简版的少了build和config这2个文件,所以配置开发环境.测试环境.生产环境的话需要自己创建env文件. 需要注意2点: 1.cli2创建项目生成的config文件里的 ...
- GAN的五大有趣应用
引言 你能看出这张照片中面部的共同点吗? 这些人都不是真实存在的!这些面部图像都是由GAN技术生成的. "GAN"这个词是由Ian Goodfellow在2014年提出的,但相关概 ...
- python之字符编码与转码
说起python编码,真是句句心酸,今天终于是,终于梳理清楚了,下面我们就来一起揭开py编码的真相吧! 一,什么是编码? 其实基本概念很简单.我们都知道消息,那么消息就是人类所能理解的,简单易懂的存在 ...
- SpringBoot 集成多数据源
一个项目中怎么划分数据库,可以通过具体业务需求. 项目中数据源怎么如何划分,通过注解的方式@Datasource(ref="") 在方法上指定,会连接指定的数据源,这种方式比较繁琐 ...
- Java 垃圾回收机制方法,判断对象存活算法
垃圾回收机制: 不定时去堆内存中清理不可达对象.不可达的对象并不会马上就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回 ...
- SpringBoot常见注解的解释
@Component 这个注解类似SSM中的Controller和Service注解 ,将加了这个注解的类装配到Sping容器内,这样就可以在其他类用@Autowired注解实现依赖注入. @Conf ...
- MATLAB 随机过程基本理论
一.平稳随机过程 1.严平稳随机过程 clc clear n=0:1000; x=randn(1,1001); subplot(211),plot(n,x); xlabel('n');ylabel(' ...