外观模式

模式定义

外观模式(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

最新文章

  1. Java基础知识系列——数组
  2. assign,copy,strong,weak,nonatomic的理解
  3. JNI 系统钩子
  4. Kooboo CMS的安装步骤
  5. jQuery表格操作
  6. 医院API免费接口的公布
  7. cocos2d-lua ARPG手机游戏《烈焰遮天》(客户端+服务端+数据库)发布说明
  8. win7配置自己的IIS服务器亲自做的图文很详细
  9. mybatis快速入门(五)
  10. 自学WPF之Binding(二)
  11. http响应结构分析
  12. c博客作业--函数
  13. 百度上传插件---webuploader的使用
  14. GPU、CPU、FPGA
  15. linux笔记_day04
  16. Django中ORM系统多表数据操作
  17. Synergy软件的基本配置/使用(详细教程)
  18. SLES12SP2使用总结
  19. vue-cli、create-react-app 项目如何查看打包分析?
  20. FFMPEG Qt视频播放器

热门文章

  1. python的C扩展调用,使用原生的python-C-Api
  2. ubuntu 远程 window
  3. 14. LiveBos编号自动生成
  4. shell脚本基础-起始句的含义
  5. IOS抓包工具Stream——让移动端的抓包变得轻而易举
  6. Dapper操作MySQL数据库获取JSON数据中文乱码
  7. 支付宝小程序获取 user_id(openid) ThinkPHP版
  8. Mac brew命令的使用
  9. 【2019牛客暑期多校第一场】E题ABBA
  10. 使命召唤:战区国际服ID注册与登录