深入浅出《设计模式》之外观模式(C++)
前言
模式介绍
外观模式相比较之下比较简单,模式设计中定义是为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口是的这一子系统更加容易使用。
如果不理解呢,简单些说就是外观模式提供了为内部提供了同意的接口层,解耦了子系统和客户端,这样客户端只需要知道外观类存在即可,不需要知道具体子系统是如何实现的。举一个简单的例子,海参面馆中两个主打面食是:
海参炒面
辣根汤面
两个主打面食都由一个师傅来做,这个师傅会这两种面食的做法。具体的做法呢如下:
- 海参炒面
1. 剥蒜
2. 拉面
3. 做汤底
- 辣根汤面
1. 制作辣根
这两种面食都有复杂的做法,调用者如果直接调用这种步骤,会让调用者与师傅的耦合性很高,如果有一天制作步骤改了,辣根汤面要剥蒜,那就需要修改调用者接口,这样是不可以的。
所以这时候师傅就是一个外观类,调用者只需要和他说,我需要一份海参炒面或者辣根汤面即可,具体如何做,就是师傅的事情了。外部不需要管。UML类图如下:
UML类图

代码实例
下面是剥蒜类实现,非常简单,只完成剥蒜动作即可。
#ifndef GRALIC_H
#define GRALIC_H
class gralic
{
public:
gralic();
~gralic();
public:
void peelinggralic();
};
#endif // GRALIC_H
#include <iostream>
#include "gralic.h"
gralic::gralic()
{
}
gralic::~gralic()
{
}
void gralic::peelinggralic()
{
std::cout << "开始剥蒜啦!!!" << std::endl;
}
下面是拉面类实现,只实现拉面动作即可。
#ifndef NOODLE_H
#define NOODLE_H
class noodle
{
public:
noodle();
~noodle();
public:
void makenoodle();
};
#endif // NOODLE_H
#include <iostream>
#include "noodle.h"
noodle::noodle()
{
}
noodle::~noodle()
{
}
void noodle::makenoodle()
{
std::cout << "开始拉面啦!!!" << std::endl;
}
其余子系统类似,就不在此展示了,包括:做汤底类和制作辣根类。
下面是外观模式,厨师师傅类,包含两个接口:制作海参炒面和辣根汤面。但是实现部分是使用各个子系统中的类和接口完成的,完成了客户端调用的解耦动作。
#ifndef COOKERFACADE_H
#define COOKERFACADE_H
class gralic;
class noodle;
class soup;
class lagen;
class cookerfacade
{
public:
cookerfacade();
~cookerfacade();
public:
void makehaishennoodle();
void makelagennoodle();
private:
gralic *m_gra;
noodle *m_noo;
soup *m_so;
lagen *m_lg;
};
#endif // COOKERFACADE_H
#include <iostream>
#include "cookerfacade.h"
#include "gralic.h"
#include "noodle.h"
#include "soup.h"
#include "lagen.h"
cookerfacade::cookerfacade()
{
m_gra = new gralic();
m_noo = new noodle();
m_so = new soup();
m_lg = new lagen();
}
cookerfacade::~cookerfacade()
{
delete m_gra; m_gra = NULL;
delete m_noo; m_noo = NULL;
delete m_so; m_so = NULL;
delete m_lg; m_lg = NULL;
}
void cookerfacade::makehaishennoodle()
{
m_gra->peelinggralic();
m_noo->makenoodle();
m_so->makesoup();
std::cout << "开始做海参炒面啦!!!" << std::endl;
}
void cookerfacade::makelagennoodle()
{
m_lg->makelagen();
std::cout << "开始作辣根汤面啦!!!" << std::endl;
}
下面是客户端代码,可以很明显的看出他只需要知道外观师傅的类即可,别的细节并不需要知道。
#include <iostream>
#include "cookerfacade.h"
using namespace std;
int main()
{
cookerfacade *cf = new cookerfacade();
cout << "老板,来一份辣根汤面!!!" << endl;
cf->makelagennoodle();
cout << "老板,换一份海参炒面!!!" << endl;
cf->makehaishennoodle();
return 0;
}
下面是编译需要的CMakeLists.txt文件:
cmake_minimum_required(VERSION 2.8)
project(cooker-facade)
set(SRC_LIST main.cpp soup.h soup.cpp gralic.h gralic.cpp cookerfacade.h cookerfacade.cpp noodle.h noodle.cpp
lagen.h lagen.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})
编译运行结果
外观模式的源代码下载位置是:https://github.com/erguangqiang/freesir_headfirst/blob/master/cooker-facade.tar.gz
代码运行的结果如下:
blog@blog-VirtualBox:~/build-cooker-facade-unknown-Default$ ./cooker-facade
老板,来一份辣根汤面!!!
开始制作辣根!!!
开始作辣根汤面啦!!!
老板,换一份海参炒面!!!
开始剥蒜啦!!!
开始拉面啦!!!
开始做汤底啦!!!
开始做海参炒面啦!!!
结束语
其实外观模式我们可能一直在用,只是我们不知道自己在用外观模式而已,平时我们开发一个系统的时候,对外API完全封装内部子系统接口,以达到便于扩展可维护的目的,其实用的就是外观模式。这种模式可以充分解耦客户端和子系统。同时也是应用比较广比较简单的设计模式。
深入浅出《设计模式》之外观模式(C++)的更多相关文章
- 每天一个设计模式-2 外观模式(Facade)
每天一个设计模式-2 外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...
- C#设计模式(11)——外观模式(Facade Pattern)
一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...
- 乐在其中设计模式(C#) - 外观模式(Facade Pattern)
原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...
- 设计模式之 外观模式详解(Service第三者插足,让action与dao分手)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...
- 8.4 GOF设计模式三: 外观模式 Facade
GOF设计模式三: 外观模式 Facade “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...
- 北风设计模式课程---外观模式(Facade)总结
北风设计模式课程---外观模式(Facade)总结 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用户获得装备,我可以先装备 ...
- js设计模式——2.外观模式
js设计模式——2.外观模式
- python设计模式之外观模式
python设计模式之外观模式 系统会随着演化变得非常复杂,最终形成大量的(并且有时是令人迷惑的)类和交互,这种情况并不少见.许多情况下,我们并不想把这种复杂性暴露给客户端.外观设计模式有助于隐藏系统 ...
- java设计模式之外观模式(门面模式)
针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下. 一.概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计 ...
- 【GOF23设计模式】外观模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_外观模式.公司注册流程.迪米特法则 package com.test.facade; public interface 工 ...
随机推荐
- js对象属性方法
window对象方法方法: 1.alert():显示带有一段消息和确认按钮的警告框 2.prompt():显示可提示用户输入的对话框 3.fonfirm():显示带有一段消息以及确认按钮和取消按钮的对 ...
- python字符减运算
在C语言等高级语言中,字符之间的减运算都是支持的,但是python不然,在python中直接进行字符减运算是不被允许的. >>> print('c'-'a') Traceback ( ...
- JSAPI签权
JSAPI鉴权----钉钉H5开发 虽钉钉开发文档上写着不需要JSAPI签权,但这仅仅是针对Android手机 所以为了保险起见,在使用JSAPI前,都需要签权. 否则:dd.ready({}) 将不 ...
- [Go] gocron源码阅读-通过第三方cli包实现命令行参数获取和管理
gocron源码中使用的是下面这个第三方包来实现的,下面就单独的拿出来测试以下效果,和官方flag包差不多 go get github.com/urfave/cli package main impo ...
- 第十七章 Metasploit Framework
渗透测试者的困扰▪ 需要掌握数百个工具软件,上千个命令参数,实在记不住▪ 新出现的漏洞PoC/EXP有不同的运行环境要求,准备工作繁琐▪ 大部分时间都在学习使用不同工具的使用习惯,如果能统一就好了▪ ...
- day56_9_20orm中的关键字段,orm查询13方法整合,查询优化和事务。
一.常用字段. 在orm中有一些字段是常用字段: 1.AutoField 这个字段是自增的,必须填入参数primary_key=True,也就是说这个字段是表的主键,如果表类中没有自增列,就会自动创建 ...
- CF-weekly4 D. Haar Features
https://codeforces.com/gym/253910/problem/D D. Haar Features time limit per test 1 second memory lim ...
- Vue 使用comouted计算属性
computed计算属性 使用方法见代码: <!doctype html> <html lang="en"> <head> <meta c ...
- 第09组 Beta版本演示
组长博客 本组(组名)所有成员 短学号 姓名 2236 王耀鑫(组长) 2210 陈超颖 2209 陈湘怡 2228 许培荣 2204 滕佳 2205 何佳琳 2237 沈梓耀 2233 陈志荣 22 ...
- webrtc笔记(4): kurento 部署
kurento是一个开源的webrtc mcu服务器,按官方的文档,建议在ubtntu上安装,过程如下: 注:建议先切换到root身份,如果不是root身份登录的,下列命令,请自行加上sudo . 另 ...