前言

实际上在软件系统开发的过程中经常会遇到这样的情况:可能你实现了一些接口(或者不同的功能模块),而这些接口(模块)都分布在几个类中(比如 A 和 B、C、D):A 中实现了一些接口,B 中实现一些接口(或者 A 代表一个独立模块,B、C、D 代表另一些独立模块)。然后你的客户(并不清楚你的具体接口到底是在哪个类中实现的,而且他们绝大多数的需求只是简单的组合: A、B、C、D 四个接口的组合,而且并不关心这些结果的内部细节。因此,在设计开发中可以通过一个叫做 Façade 的模式来解决上面的问题。我们可以为上述四个接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口降低接口调用的复杂度,简化客户端之间的互相联系


一、外观模式( Facade 模式)

在C++中,Facade模式的实现非常简单,本质上还是通过组合方式实现的。在SubSystem1、Sub system2中各自定义好接口Operation,然后将两者的指针存放在类Facade中,通过接口OperationWrapper进行调用。UML图如下:
Facade 模式示意图

二、具体源码

1.Facade.h

代码如下(示例):

#ifndef _FACADE_H_ 
#define _FACADE_H_ 

#include <iostream>

class Subsystem1
{
public:

  Subsystem1();
  ~Subsystem1();
  void Operation();

protected:
private:
};

class Subsystem2
{
public:

  Subsystem2();
  ~Subsystem2();
  void Operation();

protected:
private:
};

//通过组合的方式及进行调用
class Facade
{
public:

  Facade();
  Facade(Subsystem1* subs1In, Subsystem2* subs2In);
  ~Facade();
  void OperationWrapper();

protected:
private:
  //存放对应的指针
  Subsystem1* _subs1;
  Subsystem2* _subs2;
};
#endif //_FACADE_H_

2.Facade.cpp

代码如下(示例):

#include "Facade.h" 

Subsystem1::Subsystem1()
{
}

Subsystem1::~Subsystem1()
{
}

void Subsystem1::Operation()
{
  std::cout << "Subsystem1 operation.." << std::endl;
}

Subsystem2::Subsystem2()
{
}

Subsystem2::~Subsystem2()
{
}

void Subsystem2::Operation()
{
  std::cout << "Subsystem2 operation.." << std::endl;
}

Facade::Facade()
{
  //方便起见,直接在这里进行了Subsystem1、Subsystem2的定义
  //当然,这些类成员也可以通过接口从外部传入进行初始化
  this->_subs1 = new Subsystem1();
  this->_subs2 = new Subsystem2();
}

Facade::Facade(Subsystem1* subs1In, Subsystem2* subs2In)
{
  this->_subs1 = subs1In;
  this->_subs2 = subs2In;
}

Facade::~Facade()
{
  delete _subs1;
  delete _subs2;
}

void Facade::OperationWrapper()
{
  this->_subs1->Operation();
  this->_subs2->Operation();
}
}

3.main.cpp

代码如下(示例):

#include "Facade.h" 

int main(int argc, char* argv[])
{
  Facade* f = new Facade();
  f->OperationWrapper();

  std::cout << "Second Define!!!" << std::endl;

  Subsystem1* subPtr1 = new Subsystem1();
  Subsystem2* subPtr2 = new Subsystem2();
  Facade* f2 = new Facade(subPtr1, subPtr2);

  f2->OperationWrapper();

  return 0;
}

三、运行结果

Facade模式运行结果如下:
 Facade模式运行结果


总结

Façade 模式在高层提供了一个统一的接口,为子系统中的一组接口提供一个一致的界面,解耦了系统。这样设计的好处就是减少系统相互依赖,提高灵活性与安全性,客户只需调用统一的接口就可以顺利调用相应的功能,无需关心内部细节的具体实现。但是这样设计明显违反了开闭原则,如果需要进行功能的添加或者删减,就比较麻烦,需要对源码进行重构。


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐