11 外观模式

原文转载:https://blog.csdn.net/sinat_21107433/article/details/102752643

好不容易盼到周末啦!Jungle想吃点好的犒劳自己!吃什么呢?回锅肉!是的,吃回锅肉!

可是这过程好麻烦啊,先得去市场里买肉,买回来得洗好,然后切好,再炒肉,最后才能吃上!不仅过程繁杂,而且Jungle还得跟市场、厨房打交道,想想都头大。

如果有个厨师就好了,Jungle直接告诉厨师“我要吃回锅肉”,20分钟后厨师直接端上来就开吃。而中间那些买肉洗肉切肉的过程Jungle统统不关心了,而且Jungle也不必再关心市场和厨房,直接和厨师说句话就ok!真是方便!

 在这个例子中,厨师整合了一系列复杂的过程,外界(Jungle)只需与厨师交互即可。在软件设计模式中,有一类设计模式正式如此——外观模式。

1.外观模式简介

外观模式是一种使用频率较高的设计模式,它提供一个外观角色封装多个复杂的子系统,简化客户端与子系统之间的交互,方便客户端使用。外观模式可以降低系统的耦合度。如果没有外观类,不同的客户端在需要和多个不同的子系统交互,系统中将存在复杂的引用关系,如下图。引入了外观类,原有的复杂的引用关系都由外观类实现,不同的客户端只需要与外观类交互。

外观模式:

为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

 外观模式的应用很多,比如浏览器,用户要查找什么东西,不论是浏览知乎、腾讯或者CSDN,用户都只需要打开浏览器即可,剩下的搜索工作由浏览器完成。

2.外观模式结构

外观模式的UML结构图如下所示:

外观模式一共有以下角色:

  • Facade(外观角色):外观角色可以知道多个相关子系统的功能,它将所有从客户端发来的请求委派给相应的子系统,传递给相应的子系统处理。
  • SubSystem(子系统角色):子系统是一个类,或者由多个类组成的类的集合,它实现子系统具体的功能。 

3.外观模式代码实例

电脑主机(Mainframe)中只需要按下主机的开机按钮(powerOn),即可调用其他硬件设备和软件的启动方法,如内存(Memory)的自检(selfCheck)、CPU的运行(run)、硬盘(HardDisk)的读取(read)、操作系统(OS)的载入(load)等。如果某一过程发生错误则电脑开机失败。

这里Jungle用外观模式来模拟该过程,该例子UML图如下:

3.1.子系统类

本例中一共有4个子系统,因此设计4个类:Memory、CPU、HardDisk和OS,并且每个子系统都有自己独立的流程。

 
  1. //子系统:内存

  2. class Memory

  3. {

  4. public:

  5. Memory(){}

  6. void selfCheck(){

  7. printf("…………内存自检……\n");

  8. }

  9. };

  10.  
  11. //子系统:CPU

  12. class CPU

  13. {

  14. public:

  15. CPU(){}

  16. void run(){

  17. printf("…………运行CPU运行……\n");

  18. }

  19. };

  20.  
  21. //子系统:硬盘

  22. class HardDisk

  23. {

  24. public:

  25. HardDisk(){}

  26. void read(){

  27. printf("…………读取硬盘……\n");

  28. }

  29. };

  30.  
  31. //子系统:操作系统

  32. class OS

  33. {

  34. public:

  35. OS(){}

  36. void load(){

  37. printf("…………载入操作系统……\n");

  38. }

  39. };

3.2.外观类设计

 
  1. //外观类

  2. class Facade

  3. {

  4. public:

  5. Facade(){

  6. memory = new Memory();

  7. cpu = new CPU();

  8. hardDisk = new HardDisk();

  9. os = new OS();

  10. }

  11. void powerOn(){

  12. printf("正在开机……\n");

  13. memory->selfCheck();

  14. cpu->run();

  15. hardDisk->read();

  16. os->load();

  17. printf("开机完成!\n");

  18. }

  19. private:

  20. Memory *memory;

  21. CPU *cpu;

  22. HardDisk *hardDisk;

  23. OS *os;

  24. };

3.3.客户端代码示例

 
  1. #include <iostream>

  2. #include "FacadePattern.h"

  3.  
  4. int main()

  5. {

  6. Facade *facade = new Facade();

  7. facade->powerOn();

  8.  
  9. printf("\n\n");

  10.  
  11. system("pause");

  12. return 0;

  13. }

看到了吗,客户端的代码就是如此简单,跟子系统无关! 

3.4.效果

4.总结

优点:

  • 外观模式使得客户端不必关心子系统组件,减少了与客户端交互的对象的数量,简化了客户端的编程;
  • 外观模式可以大大降低系统的耦合度;
  • 子系统的变化并不需要修改客户端,只需要适当修改外观类即可;
  • 子系统之间不会相互影响。

缺点:

  • 如果需要增加或者减少子系统,需要修改外观类,违反开闭原则
  • 并不能限制客户端直接与子系统交互,但如果加强限制,又使得系统灵活度降低。

适用场景:

  • 为访问一系列复杂的子系统提供一个统一的、简单的入口,可以使用外观模式;
  • 客户端与多个子系统之间存在很大依赖,但在客户端编程,又会增加系统耦合度,且使客户端编程复杂,可以使用外观模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值