外观模式(Facade Pattern) 是 GoF(四人帮)23 种设计模式之一,属于结构型设计模式。
它的核心思想只有一句话:
把复杂系统封装起来,对外提供一个统一、简单的接口,让使用者不需要了解内部复杂的实现。
一、为什么需要外观模式?
假设没有 Robot 类,用户想控制机器人。
他必须自己创建很多对象
cpp
EventCenter events;
Connection connection(events, options.connection);
Navigator navigator(std::make_shared<Connection>(connection));
Motion motion(std::make_shared<Connection>(connection));
Battery battery(std::make_shared<Connection>(connection));
Voice voice(std::make_shared<Connection>(connection));
Device device(std::make_shared<Connection>(connection));
然后:
cpp
connection.connect();
motion.move(...);
navigator.navigateTo(...);
battery.getState();
voice.speak(...);
你会发现:
用户必须知道:
Connection 怎么创建
EventCenter 怎么创建
Motion 怎么依赖 Connection
Navigator 怎么依赖 Connection
Battery 怎么依赖 Connection
SDK 的所有内部细节都暴露给用户了。
对于 SDK 使用者来说,非常复杂。
于是,我们增加一个:
cpp
Robot
用户变成:
cpp
auto robot = Robot::createConnected(options);
robot->motion().move(...);
robot->navigator().navigateTo(...);
robot->battery().getState();
robot->voice().speak(...);
是不是一下子简单了?
这就是外观模式。
二、Robot 为什么是外观模式?
看看 Robot 里面都有什么:
cpp
class Robot
{
private:
Connection connection_;
Motion motion_;
Navigator navigator_;
Battery battery_;
Voice voice_;
Device device_;
EventCenter events_;
};
Robot 内部拥有:
cpp
Connection
Motion
Navigator
Battery
Voice
Device
EventCenter
但是:
用户根本不知道这些对象怎么创建。
用户只看到:
cpp
robot->motion()
robot->navigator()
robot->battery()
robot->voice()
robot->device()
Robot 把所有复杂对象全部藏起来了。
这就是:
对外提供统一入口。
三、外观模式的优缺点
优点
① 使用简单
用户只需要:
cpp
Robot robot;
不需要:
了解:
几十个类。
② 降低耦合
用户:
不知道:
Connection。
以后:
Connection:
换成:
WebSocket。
用户:
代码:
不用:
修改。
③ 隐藏实现
以后:
SDK:
增加:
Camera
Lidar
Map
Task
Robot:
里面:
增加:
成员。
用户:
代码:
不用:
变。
缺点
如果:
Robot:
越来越大。
可能:
变成:
Robot
↓
管理100多个模块
就会:
越来越臃肿。
所以:
Robot:
一般:
只负责:
协调。
真正:
业务:
放:
Motion、
Battery、
Navigator。