前言

模式介绍

外观模式相比较之下比较简单,模式设计中定义是为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口是的这一子系统更加容易使用。

如果不理解呢,简单些说就是外观模式提供了为内部提供了同意的接口层,解耦了子系统和客户端,这样客户端只需要知道外观类存在即可,不需要知道具体子系统是如何实现的。举一个简单的例子,海参面馆中两个主打面食是:

  • 海参炒面

  • 辣根汤面

两个主打面食都由一个师傅来做,这个师傅会这两种面食的做法。具体的做法呢如下:

- 海参炒面

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++)的更多相关文章

  1. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  2. C#设计模式(11)——外观模式(Facade Pattern)

    一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...

  3. 乐在其中设计模式(C#) - 外观模式(Facade Pattern)

    原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...

  4. 设计模式之 外观模式详解(Service第三者插足,让action与dao分手)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...

  5. 8.4 GOF设计模式三: 外观模式 Facade

    GOF设计模式三: 外观模式 Facade  “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...

  6. 北风设计模式课程---外观模式(Facade)总结

    北风设计模式课程---外观模式(Facade)总结 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用户获得装备,我可以先装备 ...

  7. js设计模式——2.外观模式

    js设计模式——2.外观模式

  8. python设计模式之外观模式

    python设计模式之外观模式 系统会随着演化变得非常复杂,最终形成大量的(并且有时是令人迷惑的)类和交互,这种情况并不少见.许多情况下,我们并不想把这种复杂性暴露给客户端.外观设计模式有助于隐藏系统 ...

  9. java设计模式之外观模式(门面模式)

    针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下. 一.概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计 ...

  10. 【GOF23设计模式】外观模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_外观模式.公司注册流程.迪米特法则 package com.test.facade; public interface 工 ...

随机推荐

  1. python_正则表达式学习

    re.match()函数: 函数语法: re.mathch ( pattern , string , flags = 0) 参数说明: pattem 匹配的正则表达式 string 要匹配的字符串 f ...

  2. 微信小程序踩坑日记4——真机端解析json数组和开发平台不一样

    0. 引言 环境:访问服务器端php,获取json数组,并渲染在前台 问题描述:保证在开发平台上的正常运行,但是在真机端却出现了无法正确解析wx.request()返回的数据(特指无法解析res.da ...

  3. 简单web服务工作流程梳理

       一.用户访问web基本流转过程梳理 二.web框架粗略概括

  4. 1.Python网络编程_UDP(简略版)

    # -*- coding: utf-8 -*- #2019-11-24 import socket def recv(): udp_socket=socket.socket(socket.AF_INE ...

  5. 201871010111-刘佳华《面向对象程序设计(java)》第七周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第七周学习总结 实验时间 2019-10-11 1.实验目的与要求 1) 掌握四种访问权限修饰符的使用特点: (1)进一步理 ...

  6. 线程让步yield

    一.yield()的作用 yield()的作用是让步.它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权:但是,并不能保证在当前线程调用yield()之后,其 ...

  7. ubuntu建立文件或者文件夹软链接

    文件夹建立软链接(用绝对地址) ln -s 源地址  目的地址 比如我把linux文件系统rootfs_dir软链接到/home/jyg/目录下 ln -s /opt/linux/rootfs_dir ...

  8. 设计模式-抽象工厂模式(AbstractFactory)(创建型模式)

    //以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Product.h #pragma once class AbstractProductA { public: vir ...

  9. K-消亡的质数-(简单数学)

    https://ac.nowcoder.com/acm/contest/3346/K 题意:判断一个素数p是不是某两个数的立方差. 刚看到这道题一时半会都没有什么思路,看了题解恍然大悟,太久没碰数学或 ...

  10. 7.Go-用户信息和系统文件/目录

    7.1.获取操作系统用户信息 (1)os包及子包功能 os/exec包,负责执行外部命令 os/singal对输入信息的访问 os/user通过名次或ID 查询用户账号 (2)在os/user中提供了 ...