深入浅出《设计模式》之外观模式(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完全封装内部子系统接口,以达到便于扩展可维护的目的,其实用的就是外观模式。这种模式可以充分解耦客户端和子系统。同时也是应用比较广比较简单的设计模式。

(0)

相关推荐

  • C 中的大括号(花括号)有什么功能

    一般意义上,C++ 中的大括号有以下功能: 在 C/C++中大括号指明了变量的作用域: 在大括号内声明的局部变量其作用域自变量声明开始,到大括号之后终结: { } 里的内容是一个"块&quo ...

  • C++关键字之using的的用法总结

    C++ using用法总结1)配合命名空间,对命名空间权限进行管理using namespace std;//释放整个命名空间到当前作用域using std::cout;    //释放某个变量到当前 ...

  • 剑指offer之找出数组中重复数字

    剑指offer之找出数组中重复数字

  • 设计模式之☞外观模式

    简介 外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易 ...

  • 设计模式:外观模式

    外观模式(Facade) 介绍:为子系统中的一组接口提供一个统一的入口.外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程 ...

  • 设计模式之外观模式

    设计模式之外观模式

  • 详解JAVA面向对象的设计模式 (四)、外观模式

    外观模式 Facade 外观模式内容相对简单,就不写新的例子了.本篇文章摘录自 http://c.biancheng.net/view/1369.html 外观模式的定义与特点 外观(Facade)模 ...

  • 设计模式-外观模式

    定义 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 为了方便理解,我们可以看看下图,左边是未使用外观模式时,外部客户端直接调用企业中的各个子 ...

  • 无废话设计模式(10)结构型模式--外观模式

    0-前言 外观模式定义:为子系统中的一组接口提供一个一致的界面,此模式定了一个高层接口    这一接口使得这一子系统更加容易使用: 1-实现 1-1.简单UML图: 1-2.代码实现 //1.子系统A ...

  • PHP设计模式—外观模式

    定义: 外观模式(Facade):又叫门面模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 代码实例: 假设实现一个功能需要用到子系统中的四 ...

  • 结合Mybatis源码看设计模式——外观模式

    定义 提供了一个统一的接口,用来访问子系统中一群接口 适用场景 子系统复杂,增加外观模式提供简单调用接口 构建多层系统结构,用外观对象作为每层入口 详解 外观模式,主要理解外观.通俗一点可以认为这个模 ...

  • Java设计模式【命令模式】

    命令模式 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不 ...