- Published on
设计模式(10)——外观 Facade
- Authors
- Name
- Leon
十、Facade (外观模式,对象结构型模式)
1. 意图:
为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
2. 适用:
- 当你要为一个复杂子系统提供一个简单接口时。
- 客户程序与抽象类的实现部分之间存在着很大的依赖性。
- 当你需要构建一个层次结构的子系统时,使用 facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过 facade 进行通讯,从而简化了它们之间的依赖关系。
3. 类图:
4. Facade 模式优点:
客户端不再需要关注实例化时应该使用哪个实现类,直接调用 Facade 提供的方法就可以了,因为 Facade 类提供的方法的方法名对于客户端来说已经很友好了。
5. 中间层思考:
很明显可以看出外观模式的中间层就是在客户和复杂的子系统之间提供了一套简洁的接口,让客户对子系统的了解程度和耦合达到最小。在外观模式中也不会限制客户直接使用子系统类,但这会增加耦合性,所以需要在系统的易用性的可扩展性之间作出取舍。
6. Facade 与 Adapter
Facade 外观模式与 Adapter 适配器模式有点像,它们都提供了一个中间层,中间层负责封装了一些对象,然后提供了一套接口,做的事情简直一模一样!细想,这两个模式的结构确实是基本上一致的,但是它们的目的却完全不一样。适配器模式的目的是为了兼容新模块和老系统,而加入中间层做适配。而外观模式的目的是为了降低系统使用某个外接系统的成本和耦合。再看看设计模式的定义————“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心”。也就是说设计模式是由两部分组成的,即它描述的问题以及解决方案。两个设计模式的解决方案可能是相同的,甚至可以说所有设计模式的解决方案都是相同的(添加中间层),但是所有设计模式描述的问题绝对是不相同的。还有其它很多设计模式,感觉它们的解决方案(类图)很相似,这个时候就得想想这些设计模式的出发点————它们描述的是个什么问题?
7. C++实现:
- 编写子系统类
SubSystem1
、SubSystem2
等,各子系统都有自己的函数Operation
- 编写外观类
Facade
,has-a
SubSystem1、SubSystem2等, - 通过
Facade
构造函数初始化 SubSystem1 和 SubSystem2 对象 Facade
中编写函数OperationWrapper()
调用各子系统SubSystem1
、SubSystem2
对象中的Operation()
Facade.h
// Facade.h
#pragma once
class SubSystem1 {
public:
SubSystem1();
~SubSystem1();
void Operation();
protected:
private:
};
class SubSystem2 {
public:
SubSystem2();
~SubSystem2();
void Operation();
protected:
private:
};
class Facade {
public:
Facade();
~Facade();
void OperationWrapper();
protected:
private:
SubSystem1* _subs1;
SubSystem2* _subs2;
};
Facade.cpp
// Facade.cpp
#include "Facade.h"
#include <iostream>
using namespace::std;
SubSystem1::SubSystem1() {}
SubSystem1::~SubSystem1() {}
void SubSystem1::Operation() {
cout << "Subsystem1 operation..." << endl;
}
SubSystem2::SubSystem2() {}
SubSystem2::~SubSystem2() {}
void SubSystem2::Operation() {
cout << "Subsystem2 operation..." << endl;
}
Facade::Facade() {
this->_subs1 = new SubSystem1();
this->_subs2 = new SubSystem2();
}
Facade::~Facade() {
delete _subs1;
delete _subs2;
}
void Facade::OperationWrapper() {
this->_subs1->Operation();
this->_subs2->Operation();
}
main.cpp
// main.cpp
#include "Facade.h"
#include <iostream>
using namespace::std;
int main(int argc, char* argv[]) {
Facade* f = new Facade();
f->OperationWrapper();
return 0;
}