1 定义

外观模式,又叫做门面模式,是指在与一个复杂的子系统进行交互时,为子系统提供一个高层的接口,转而和高层的接口进行交互,以符合迪米特法则(Law of Demeter,LoD)。

在软件设计中,当一个系统功能越来越强,代码越来越多,复杂度也越来越高,如果直接与系统交互,那么子系统发生改变,交互代码也要随着改变,这违背的开闭原则(Open Closed Principle,OCP)。此时,我们需要为子系统提供一个高层的接口,降低耦合度。

2 结构与一般实现

外观模式结构如下图所示,主要包含如下角色:

1.外观(Facade)角色:为多个子系统对外提供一个共同的接口。

2.子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。

3.客户(Client)角色:通过一个外观角色访问各个子系统的功能。

3 优缺点

3.1 优点

1.降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户端。

2.对客户端屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。

3.降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

3.2 缺点

1.不能很好地限制客户使用子系统类,很容易带来未知风险。

2.增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

4 适用场景

1.对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。

2.当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。

3.当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。

5 与代理模式的区别

个人理解,代理模式,是功能类的代理,也就说代理类和被代理类在功能上是相同的,代理类能增强功能类的功能。比如尤尼克斯的代理,他只能经销尤尼克斯的相关产品,尤尼克斯公司卖什么代理商就卖什么,如果想要买胜利的货品,就需要去另一家胜利的代理商。

外观模式,是子系统功能的一个抽象,不代表某一个具体的子系统,是根据客户端的想要的功能,对子系统功能的一个组合。比如大型超市,卖各种各样的货品,茅台的白酒,剑南春的白酒都卖,我们想要卖各种各样的白酒,直接去超时就可以了。

6 代码示例

在饭店点餐时,我们(客户端)和饭店厨房(子系统)由服务员(外观模式)进行了解耦,我们想要点菜时,我们告诉服务员,服务员点餐好了通知厨房做菜,我们并不需要知道我们想要吃的菜是由那个厨子去做,不需要找厨子本人进行点菜。

我们现在有三个卖饭窗口,卖不同的食物,我们想要的食物可能不在某一个窗口,我们可以通过调用外观进行点菜。

6.1 饭菜窗口A MealWindowA

/*** @program: design-pattern-learning* @author: zgr* @create: 2021-09-24 10:55**/
public class MealWindowA {public MealWindowA(){System.out.println("食堂饭菜A窗口,主营陕西特色");}public void sellOilNoddles(){System.out.println("好吃不贵的油泼面啦!");}public void sellSaoZiNoddles(){System.out.println("好吃不贵的臊子面啦!");}public void sellSpecialNoddles(){System.out.println("好吃不贵的Biáng Biáng面啦!");}
}

6.2 饭菜窗口B MealWindowB

/*** @program: design-pattern-learning* @author: zgr* @create: 2021-09-24 11:01**/
public class MealWindowB {public MealWindowB(){System.out.println("食堂饭菜B窗口,主营四川特色");}public void sellFish(){System.out.println("巴适得板的水煮鱼哈!");}public void sellMeat(){System.out.println("巴适得板的水煮肉片哈!");}public void sellBlood(){System.out.println("巴适得板的毛血旺哈!");}
}

6.3 饭菜窗口C MealWindowC

/*** @program: design-pattern-learning* @author: zgr* @create: 2021-09-24 10:55**/
public class MealWindowC {public MealWindowC(){System.out.println("食堂饭菜C窗口,主营东北特色");}public void sellChickenWithMushrooms(){System.out.println("贼拉好吃的小鸡炖蘑菇!");}public void sellShaZhuCai(){System.out.println("贼拉好吃的酸菜汆白肉!");}public void sellGuoBaoRou(){System.out.println("贼拉好吃的锅包肉!");}
}

6.4 外观 MyFacade

/*** @program: design-pattern-learning* @author: zgr* @create: 2021-09-24 11:12**/
public class MyFacade {private MealWindowA mealWindowA;private MealWindowB mealWindowB;private MealWindowC mealWindowC;public MyFacade(){this.mealWindowA = new MealWindowA();this.mealWindowB = new MealWindowB();this.mealWindowC = new MealWindowC();}public void buyMealA(){mealWindowA.sellSaoZiNoddles();mealWindowB.sellBlood();mealWindowC.sellGuoBaoRou();}public void buyMealB(){mealWindowB.sellMeat();mealWindowB.sellFish();mealWindowC.sellShaZhuCai();}
}

6.5 主函数 MainClass

/*** @program: design-pattern-learning* @author: zgr* @create: 2021-09-24 10:53**/
public class MainClass {public static void main(String[] args) {MyFacade facade = new MyFacade();System.out.println();System.out.println();System.out.println();System.out.println("我是一号服务员,请点菜,我给你买");facade.buyMealA();System.out.println();System.out.println("我是二号服务员,请点菜,我给你买");facade.buyMealB();}
}

6.6 运行结果

6.7 总结

代码可以看出,卖饭窗口ABC是一个子系统,外观是ABC子系统的一个合集,而不仅仅是代理一个窗口而已。本例代码中,外观模式只有两个功能,实际中,外观应根据客户端需要,对子系统的功能进行合集抽象,以满足功能需求。

7 引用

1.《大话设计模式》

2.外观模式(Facade模式)详解

8 源代码

https://github.com/airhonor/design-pattern-learning/tree/main/src/com/hz/design/pattern/facade

设计模式---外观(Facade)模式相关推荐

  1. 设计模式学习笔记——外观(Facade)模式

    设计模式学习笔记--外观(Facade)模式 @(设计模式)[设计模式, 外观模式, facade] 设计模式学习笔记外观Facade模式 基本介绍 外观案例 类图 实现代码 Database类 ma ...

  2. 外观(Facade)模式

    文章目录 外观(Facade)模式 1. 意图 2. 别名 3. 动机 4. 适用性 5. 结构 6. 参与者 7. 协作 8. 效果 9. 实现 10. 代码示例 11. 已知应用 12. 相关模式 ...

  3. facade java_Java设计模式之Facade模式

    Java设计模式之Facade模式  GOF<设计模式>一书对Facade模式是这样描述的: 为子系统中的一组接口提供一个统一接口.Facade模式定义了一个更高层的接口,使子系统更加容易 ...

  4. 设计模式之九 --- 外观(Facade)模式

    [1]基本概念 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. [2]简单分析 我们先来看下该设计模式的UML结构图: ...

  5. C++设计模式之Facade模式(外观模式)

    Facade模式(外观模式),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用. 我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象, ...

  6. 设计模式--门面(Facade)模式

    模式定义 为子系统中的一组接口提供一个一致(稳定)的界面,Facade模式定义了一个高层接口,这个接口使得这个子系统更加容易使用(复用) 类图 应用场景 1.当你需要使用复杂子系统的有限但直接的接口时 ...

  7. 设计模式:Facade模式

    Facade模式--简单窗口 当调用大型程序进行处理时,我们需要格外注意那些数量庞大的类之间错综复杂的关系.不过有一种更简单的做法,就是为这个大型程序提供一个"窗口".这样,我们就 ...

  8. 设计模式之facade模式

    从理论上讲facade模式,就是在系统中一个对象需要调用某些相似的功能,而将这些相似的功能进行封装,而留给需要调用的对象一个接口,这个接口不是我们编程意义上的接口,实际可以是一个接口,或者一个类.供调 ...

  9. 浅学设计模式之外观Facade模式

    外观模式是软件工程中常用的一种软件设计模式.它为子系统中的一组接口提供一个统一的高层接口.使用子系统更容易使用. 下图是状态模式的UML图. 结构 Facade 这个外观类为子系统中Packages ...

  10. java设计模式之Facade模式

    介绍外观模式之前,首先让我们来看下面的例子: 假设我们现有一个对外接口FacadeService,里面有一个对外的方法a(): public interface FacadeService {publ ...

最新文章

  1. 超级智能的定义,一个已经诞生并不断深刻影响人类的新智能
  2. 高速串行总线系列(5)总线的各种基础问题
  3. 鸿蒙系统正式版官方下载,华为鸿蒙os2.0系统app正式版
  4. php 剪贴板,之Windows中的剪贴板
  5. 微服务架构设计模式~根据业务能力进行服务拆分
  6. 安装Windows 2003 域控制器
  7. mysql mvcc gap lock_为什么说 MVCC 和 Gap Lock 解决了 MySQL 的幻读问题
  8. iptables命令详解
  9. 牛皮!竟然有大佬基于 Spring Boot + Vue 开发了一套网易云QQ音乐(附源码)。。。...
  10. 计算机模拟技术在材料中的应用,浅谈计算机模拟技术在材料科学中的应用.doc...
  11. Vue引入百度地图API,添加点击地图拾取坐标并且标记和地址搜索功能
  12. 独门秘籍 针式打印机换针小窍门
  13. 计算机高级语言程序的流程控制结构,汇编语言(四) - 程序结构
  14. 高通平台的耳机检测(msm8909)
  15. 数据分析师需要考试或考证吗?
  16. 非分区表转换为分区表的三种方式
  17. JavaCV音视频开发宝典:vb8和vp9编码的webm格式视频文件转成mp4文件
  18. 初识Openlayers
  19. 【LeetCode刷题日记】常用算法基础和理解及运用
  20. 替换android的hal支持阵列麦拾音

热门文章

  1. VMware ESX/ESXi 主机上的 VMFS 卷被锁定
  2. 1.14食油大学acm训练赛NO.6
  3. 55欧式空间02——正交矩阵、欧氏空间的同构
  4. 小电科技CTO“肉山”芦宇峰:互联网过35岁就遭裁员?如何应对职业危机
  5. php天气预报接口,利用中国天气预报接口实现简单天气预报
  6. React 在react中实现鼠标拖拽移动盒子和图片(基于Ant-Design-Pro 4实现)
  7. 谢烟客---------Linux之文件系统管理挂载
  8. 使用Perfmon和PAL工具查看Server性能--PerfMon入门指南
  9. Oracle 11g 修改表的所属表空间
  10. 电路原理图(SCH)相关知识详解