[定义]:
在GOF的《设计模式:可复用面向对象软件的基础》一书中对外观模式是这样说的:将子系统中的一组接口提供一个一致的界面,
外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
举例1:
我们在使用visual studio进行编译C++代码时,你只是在菜单中选择了Build,然后visual studio就开始了一堆的编译工作,当单击这个Build按钮时,Build在幕后,将任务分发给不同的子系统去完成,最终子系统进行协作完成了整个的编译任务。而这样隐藏一些复杂操作,只提供一个更高层的统一接口。
结合定义理解:子系统中的一组接口,就好比上面举得例子中的语法分析,生成中间代码,生成汇编代码,链接成可执行程序或库;外观模式定义的一个高层接口,就好比上面说的Build按钮,通过这样的一个Build按钮,让编译器更加容易使用。
举例2:
去茶馆喝茶,只要跟服务员说明喝什么茶,服务员安排烧水、拿茶叶、泡茶等动作
结合定义理解:将子系统中的一组接口提供一个一致的界面,就是将烧水、拿茶叶、泡茶等动作组成一个接口,接口是XX茶(比如龙井茶、红茶等),外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,这个高层接口就是服务员,你只要和服务员沟通即可,复杂子系统的事由服务员去安排。
[外观模式出现的意义]:
将如上例子反过来想,如果没有build按钮和服务员,就得自己动手和复杂的子系统进行交互。
[优点]
它对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目,并使得子系统使用起来更加方便;
它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的;松耦合系统使得子系统的组件变化不会影响到它的客户。
外观模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。外观模式可以消除复杂的循环依赖关系。这一点在客户程序与子系统是分别实现的时候尤为重要。
[使用场合]
当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变的越来越复杂。大多数模式使用时都会产生更多更小的类。
这使得子系统更具有可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。外观模式可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层;当客户程序与抽象类的实现部分之间存在很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当需要构建一个层次结构的子系统时,使用外观模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,我们就可以让它们仅通过Facade进行通讯,
从而简化了它们之间的依赖关系。
[举例说明]
#include <iostream>
using namespace std;
// 语法分析子系统
class CSyntaxParser
{
public:
void SyntaxParser()
{
cout << "Syntax Parser" << endl;
}
};
// 生成中间代码子系统
class CGenMidCode
{
public:
void GenMidCode()
{
cout << "Generate middle code" << endl;
}
};
// 生成汇编代码子系统
class CGenAssemblyCode
{
public:
void GenAssemblyCode()
{
cout << "Generate assembly code" << endl;
}
};
// 链接生成可执行应用程序或库子系统
class CLinkSystem
{
public:
void LinkSystem()
{
cout << "Link System" << endl;
}
};
//外观接口,在该类中定义各种子系统对象并进行交互
class Facade
{
public:
void Compile()
{
CSyntaxParser syntaxParser;
CGenMidCode genMidCode;
CGenAssemblyCode genAssemblyCode;
CLinkSystem linkSystem;
syntaxParser.SyntaxParser();
genMidCode.GenMidCode();
genAssemblyCode.GenAssemblyCode();
linkSystem.LinkSystem();
}
};
// 客户端,定义外观接口对象即可,想要什么就调用外观接口内的方法实现需求即可
int main()
{
Facade facade;
facade.Compile();
}
//输出
//Syntax Parser
//Generate middle code
//Generate assembly code
//Link System