1、描述
外观是一种结构型设计模式,能为复杂系统、程序库或框架提供一个简单(但有限)的接口
外观模式注重“统一的对象”,也就是提供一个访问子系统的接口,除了这个接口不允许有任何访问子系统的行为发生。
优点:1、减少系统的相互依赖; 2、提高了灵活性; 3、提高了安全性;
缺点:不符合开闭原则,一旦外观类出现错误,唯一能做的事情就是修改外观类的代码,风险比较大。
2、结构图
- 外观(Facade)提供了一种访问特定子系统功能的便捷方式,其了解如何重定向客户端请求,知晓如何操作一些活动部件。
- 子系统(SubSystem)可以同时有一个或多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户端而已。
3、C++代码
#include <string>
#include <iostream>
//子系统可以接收外观类的请求,也可以被客户端直接使用
//对于子系统来说,外观类也是另一个客户,而不是子系统的一部分。
class Subsystem1 {
public:
std::string Operation1() const {
return "Subsystem1: Ready!\n";
}
// ...
std::string OperationN() const {
return "Subsystem1: Go!\n";
}
};
//一些外观类可以同时使用多个子系统
class Subsystem2 {
public:
std::string Operation1() const {
return "Subsystem2: Get ready!\n";
}
// ...
std::string OperationZ() const {
return "Subsystem2: Fire!\n";
}
};
//外观类为一个或几个子系统的复杂逻辑提供了一个简单的接口。
//外观类将客户端的请求分派给合适的子系统。
//外观类也要负责管理子系统的生命周期。
class Facade {
protected:
Subsystem1 *subsystem1_;
Subsystem2 *subsystem2_;
//可以根据需求使用现有的子系统对象或者自己创建新的
public:
Facade(
Subsystem1 *subsystem1 = nullptr,
Subsystem2 *subsystem2 = nullptr) {
this->subsystem1_ = subsystem1 ?: new Subsystem1;
this->subsystem2_ = subsystem2 ?: new Subsystem2;
}
~Facade() {
delete subsystem1_;
delete subsystem2_;
}
//客户只需要使用外观类提供的简单接口。
std::string Operation() {
std::string result = "Facade initializes subsystems:\n";
result += this->subsystem1_->Operation1();
result += this->subsystem2_->Operation1();
result += "Facade orders subsystems to perform the action:\n";
result += this->subsystem1_->OperationN();
result += this->subsystem2_->OperationZ();
return result;
}
};
//客户代码只需要外观类提供的简单接口,甚至可以不知道子系统的存在
void ClientCode(Facade *facade) {
// ...
std::cout << facade->Operation();
// ...
}
//客户端代码可能有已经创建好的子系统对象。可能值得使用这些对象初始化Facade
int main() {
Subsystem1 *subsystem1 = new Subsystem1;
Subsystem2 *subsystem2 = new Subsystem2;
Facade *facade = new Facade(subsystem1, subsystem2);
ClientCode(facade);
delete facade;
return 0;
}
参考