门面模式是一种结构型设计模式,它为复杂的子系统提供了一个简化的接口,隐藏了系统的复杂性,使客户端更容易使用。
主要特点
-
简化接口:为复杂的子系统提供一个更简单、更统一的接口
-
解耦:将客户端与子系统解耦,使子系统更容易修改和扩展
-
层次化:为子系统创建一个更高层次的接口,使子系统更易于使用
结构组成
-
Facade (门面):提供简化的接口,将客户端请求委派给适当的子系统对象
-
Subsystem Classes (子系统类):实现子系统的功能,处理Facade分配的工作
适用场景
-
当需要为复杂的子系统提供一个简单的接口时
-
当需要将子系统组织成层次结构时
-
当需要减少客户端与子系统的耦合度时
优点
-
简化了客户端与子系统的交互
-
将客户端与子系统解耦,使子系统更容易修改
-
减少了客户端需要处理的对象数量
示例代码
#include <iostream>
#include <memory>
#include <vector>
// 更复杂的子系统示例
class Database {
public:
void Connect() { std::cout << "数据库连接建立" << std::endl; }
void Disconnect() { std::cout << "数据库连接关闭" << std::endl; }
void ExecuteQuery(const std::string& query) {
std::cout << "执行查询: " << query << std::endl;
}
};
class Cache {
public:
void Connect() { std::cout << "缓存连接建立" << std::endl; }
void Disconnect() { std::cout << "缓存连接关闭" << std::endl; }
void Set(const std::string& key, const std::string& value) {
std::cout << "设置缓存: " << key << " = " << value << std::endl;
}
std::string Get(const std::string& key) {
std::cout << "获取缓存: " << key << std::endl;
return "cached_value";
}
};
class Logger {
public:
void Log(const std::string& message) {
std::cout << "日志记录: " << message << std::endl;
}
};
// 智能指针管理的门面类
class SystemFacade {
private:
std::unique_ptr<Database> db;
std::unique_ptr<Cache> cache;
std::unique_ptr<Logger> logger;
public:
SystemFacade()
: db(std::make_unique<Database>()),
cache(std::make_unique<Cache>()),
logger(std::make_unique<Logger>()) {
Initialize();
}
~SystemFacade() {
Shutdown();
}
void Initialize() {
db->Connect();
cache->Connect();
logger->Log("系统初始化完成");
}
void Shutdown() {
cache->Disconnect();
db->Disconnect();
logger->Log("系统关闭");
}
void PerformTask(const std::string& query) {
logger->Log("开始执行任务");
// 先查缓存
std::string cached = cache->Get("query_cache");
if (!cached.empty()) {
logger->Log("从缓存获取结果");
return;
}
// 缓存没有则查数据库
db->ExecuteQuery(query);
cache->Set("query_cache", "result_data");
logger->Log("任务执行完成");
}
};
int main() {
{
SystemFacade system;
system.PerformTask("SELECT * FROM users");
// 离开作用域时自动调用析构函数关闭资源
}
return 0;
}
结构
要点总结
从客户程序的角度来看,Façade模式简化了整个组件系统的接口,对于组件内部与外部客户程序来说,达到了一种"解耦"的效果:内部子系统的任何变化不会影响到Façade接口的变化。
Façade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Façade很多时候更是一种架构设计模式。
Façade设计模式并非一个集装箱,可以任意地放进任何多个对象。Façade模式中组件的内部应该是"相互耦合关系比较大的一系列组件",而不是一个简单的功能集合。
门面模式在日常开发中很常见,比如各种库的API封装、框架的入口类等,都是门面模式的应用。