外观模式-分析和C++实现
时间:2022-07-26
本文章向大家介绍外观模式-分析和C++实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
外观模式结构
- Facade 定义子系统的多个模块对外的高层接口,通常需要调用内部的多个模块,从而把客户的请求代理给适当的子系统。
- 模块 接受Facade对象的委派,真正实现功能,各个模块之间可能有交互。但请注意,Facade对象知道各个模块,但是各个模块不应该知道Facade对象。
外观模式实例代码
由于上面外观模式的结构过于抽象,因此把它具体点。假设系统内有三个模块,分别是AModule,BModule和CModule,它们分别有一个示意的方法,那么整体结构如下图所示。
代码实现
#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接口,那么用于子系统内部的接口功能就不用暴露给子系统的外部。
外观接口的本质
封装交互,简化调用
- WCF的安全审核——记录谁在敲打你的门
- Step By Step 一步一步写网站[1] —— 填加数据
- 五个解决方案让MongoDB拥有RDBMS的鲁棒性事务
- Step By Step 一步一步写网站[1] —— 帧间压缩,表单控件
- [WCF-Discovery]如何利用”发现代理”实现可用服务的实时维护?
- 深度学习与机器学习
- Step By Step 一步一步写网站[1] —— 填加数据(二)
- [WCF-Discovery]让服务自动发送上/下线通知[原理篇]
- [WCF-Discovery]让服务自动发送上/下线通知[实例篇]
- [WCF权限控制]利用WCF自定义授权模式提供当前Principal[实例篇]
- [WCF权限控制]利用WCF自定义授权模式提供当前Principal[原理篇]
- [自定义服务器控件] 第一步:文本框。
- 检查两个数据库里的表名、字段是否一致的一种方法
- 如何在Python中从零开始实现随机森林
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Sentinel整合Apollo进行规则持久化
- DevTools(Chrome 85)的新功能
- 在Node.js中处理Zip文件
- 构建一个带身份验证的 Deno 应用
- Sentinel整合Apollo进行规则持久化(二)
- Sentinel整合Apollo进行规则持久化(三)
- BeesCMS的SQL注入漏洞
- 操作系统的演变及在云计算的应用
- 没root账号,如何安装perl包
- 从 BIO、NIO 聊到 Netty,还要手写一个 RPC 框架!毕设/项目经验稳了!
- 从100万条数据中找到极大值所在行
- 常考题 | IoU 计算
- 操作系统和并发的爱恨纠葛
- Vue Router详细教程
- C语言作图库(kplot)示例