## 外观模式结构

1. **Facade**
定义子系统的多个模块对外的高层接口,通常需要调用内部的多个模块,从而把客户的请求代理给适当的子系统。
2. **模块**
接受Facade对象的委派,真正实现功能,各个模块之间可能有交互。但请注意,Facade对象知道各个模块,但是各个模块不应该知道Facade对象。
## 外观模式实例代码
由于上面外观模式的结构过于抽象,因此把它具体点。假设系统内有三个模块,分别是**AModule**,**BModule**和**CModule**,它们分别有一个示意的方法,那么整体结构如下图所示。

### 代码实现
```cpp
#include <iostream>
#include <memory>
/**
* A模块接口
*/
class AModuleApi {
public:
virtual void testA() = 0;
virtual ~AModuleApi() {}
};
/**
* A模块接口具体实现
*/
class AModuleImpl : public AModuleApi {
public:
void testA() override
{
std::cout << "operate method testA in AModule" << std::endl;
}
};
/**
* B模块接口
*/
class BModuleApi {
public:
virtual void testB() = 0;
virtual ~BModuleApi() {}
};
/**
* C模块接口具体实现
*/
class BModuleImpl : public BModuleApi {
public:
void testB() override
{
std::cout << "operate method testB in BModule" << std::endl;
}
};
/**
* C模块接口
*/
class CModuleApi {
public:
virtual void testC() = 0;
virtual ~CModuleApi() {}
};
/**
* C模块接口具体实现
*/
class CModuleImpl : public CModuleApi {
public:
void testC() override
{
std::cout << "operate method testC in CModule" << std::endl;
}
};
/**
* 外观对象
*/
class Facade {
public:
/**
* 示意方法,满足客户需求的功能
*/
static void test()
{
/**
* 在内部实现的时候,可能会调用到内部的多个模块
* 用智能指针new模块对象,其实可以用局部对象调用,
* 考虑到模块对象可能比较大,担心占用栈空间过大
*/
std::shared_ptr<AModuleApi> aptr(new AModuleImpl());
aptr->testA();
std::shared_ptr<BModuleApi> bptr(new BModuleImpl());
bptr->testB();
std::shared_ptr<CModuleApi> cptr(new CModuleImpl());
cptr->testC();
}
};
void test()
{
Facade::test();
}
int main(int argc, char** argv)
{
test();
return 0;
}
```
运行结果:
```
operate method testA in AModule
operate method testB in BModule
operate method testC in CModule
```
以上例子,**Facade**类其实相当于**A**,**B**,**C**模块的外观界面,**Facade**类也被称为**A**,**B**,**C**模块对外的接口,那么客户端就不需要知道系统内部的实现细节,甚至客户端都不需要知道**A**,**B**,**C**模块的存在,客户端跟**Facade**类交互就好了,从而更好实现了客户端和子系统中**A**,**B**,**C**模块的解耦,让客户端更容易地使用系统。
## 外观模式的目的
外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散解耦,从而让外部能够更简单地使用子系统。这点要特别注意,因为外观是当做子系统对外接口的实现,虽然也可以在这里定义一些子系统没有到额功能,但不建议这么做。外观应该是包装已有的功能,它主要负责组合已有功能来实现客户需要,而不是添加新的实现。
## 外观模式的好处
能够选择性地暴露接口的方法,尽量减少子系统接口功能的暴露。一个模块的接口中定义的方法可以分为两部分,一部分是给子系统外部使用的,一部分是子系统内部的模块间相互调用时使用的。有了**Facade**接口,那么用于子系统内部的接口功能就不用暴露给子系统的外部。
## 外观接口的本质
**封装交互,简化调用**
- 空白目录
- 算法
- 排序
- 冒泡排序
- 选择排序
- 插入排序
- 归并排序
- 快速排序
- 计数排序
- 桶排序
- 基数排序
- 希尔排序
- 堆排序
- 二分查找
- 最小堆
- 最小索引堆
- 平衡二叉树(AVL tree)
- bitmap位图
- 布隆过滤器
- hashmap
- topK
- 跳表
- LRU Cache
- kmp
- 最小堆和堆排序
- 最短路径
- C++
- 运行时类型判断RTTI
- C++反射
- 手动实现智能指针
- 序列化实现
- rpc实现
- std::forward
- 函数指针的妙用
- C/C++
- std::function
- 同步队列
- 线程池实现
- std::promise
- 深入理解虚函数
- extern "C" 关键字讲解
- 大端小端的区别
- 简历
- 简历1
- redis
- 数据结构和对象
- sds
- list
- zskiplist
- 腾讯云redis面试题总结
- redis集群部署
- LeetCode
- 目标
- go基础
- 算法快速入门
- 数据结构篇
- 二叉树
- 链表
- 栈和队列
- 二进制
- 基础算法篇
- 二分搜索
- 排序算法
- 动态规划
- 算法思维
- 递归思维
- 滑动窗口思想
- 二叉搜索树
- 回溯法
- 其他
- 剑指offer
- 笔记
- git代理加速
- Linux
- vim大法
- vscode远程不能跳转
- cmake
- 设计模式
- 单例模式
- 简单工厂模式
- 外观模式
- 适配器模式
- 工厂方法模式
- 抽象工厂模式
- 生成器模式
- 原型模式
- 中介者模式
- 观察者模式
- 访问者模式
- 命令模式
- 网络编程
- epoll reactor模式
- linux timerfd系列函数总结
- IO
- mapreduce
- 反射器
- leo通信库
- Mutex
- Condition
- thread
- raft
- 协程
- hook
- 定时器
- 别人的面试经验
- 面试题
- vector崩溃问题
- JAVA
- Linux java环境配置
- ucore
- lab1
- FreeNOS
- leveldb
- 刷题笔记
- 回文串
- 前缀树
- 字符串查找
- 查找两个字符串a,b中的最长公共子串
- 动态规划
- golang
- 顺序循环打印实现
- 数据结构
- rpc运用
- python
- 单例
- 深拷贝浅拷贝
- 链表
- python基础题
- mysql
- 事务
- Linux
- 共享内存
- 刷题记录
- 贪心算法
- 动态规划
- 面试
- 腾讯C++面试
- 微众面试JD
- 迅雷网络面试
- 学习网址
- rabbitMq
