每日一个设计模式之【外观模式】
☁️前言🎉🎉🎉
大家好✋,我是知识汲取者😄,今天给大家带来一篇有关外观模式的学习笔记。众所周知能够熟练使用设计模式是一个优秀程序猿的必备技能,当我们在项目中选择一个或多个合适的设计模式,不仅能大大提高项目的稳健性、可移植性、可维护性,同时还能让你的代码更加精炼,具备艺术美感。
在生活中,外观模式处处可见,电脑的开机按钮、电源开关总闸等等都是拥有外观模式的思想在其中的,同样的在编程世界中,外观模式就显得更为常见了,诸如分层开发,统一的接口设计,一键**这些都可以看作是一个个外观模式的应用,外观模式提供了一个统一的接口让用户更容易操作系统,现在就让我们来好好学习一下这么一个常见且重要的设计模式吧😃
推荐阅读:
🌻外观模式概述
-
什么是外观模式?
外观模式(Facade Pattern)又称为门面模式,是一种对象结构型模式,它提供了一个统一高层次的接口,让外界通过该接口访问内部子系统的一群接口
PS:外观模式是迪米特法则的一种具体实现
-
外观模式的作用:隐蔽子系统的复杂性,简化子系统的接口,让子系统变得更加容易使用
-
外观模式的优缺点
-
优点:
- 降低了系统的耦合度。外界只需要和外观接口进行交互即可,不必与每一个子接口进行交互
- 提高了系统的灵活性。外观模式在降低了子系统与外部的耦合度,让子系统能够有更多的变化而不受外部的影响
- 提高系统的可维护性。外观模式让系统进行了分层,进一步降低了系统的耦合度,让系统的后期维护变得更加简单
- 让系统变得更加容易使用。外观模式对一群子系统的接口进行了重新封装,让复杂大量的子系统接口变成一个统一的接口,大大简化了系统的使用难度
……
-
缺点:
- 存在安全隐患。外观模式不能很好地限制客户端直接使用子系统类,很容易倒置客户端的使用者出现错误操作影响系统的正常运行,但如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性,所以鱼与熊掌不可兼得
- 模式设计较复杂,需要具有一定开发经验,如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则,导致系统维护成本很大
……
-
-
外观模式的适用场景
- 系统较为复杂,子系统较多时,推荐使用外观模式
- 客户端程序与多个子系统之间存在很大的依赖性时,推荐使用外观模式
- 想要预防低水平人员带来的风险,推荐使用外观模式
……
生活中的应用:交互机(所有信息都有交互机进行统一分发管理)、导游(旅游景区众多,游客如果想要一一了解则需要花费大量的时间,但是通过导游就可以快速了解)
编程中的应用:Java中的分层开发,也可以说是三层架构,就是利用了外观模式的设计思想,每一层都有一个统一的接口,负责和其它层进行交互,大大降低了系统的耦合度
-
外观模式的角色划分
- 外观角色(Facade):也可称之为系统窗口,是外观模式的核心角色,内部含有大量子系统的引用,负责和客户端进行交互,可以是方法、具体的类、抽象类、接口,只要能够提供一个统一的接口都可以是外观角色
- 子系统(SubSystem):是系统的主要组成部分,所有子系统共同构件一个完整的系统
- 客户端(Client):是系统的外部使用者(对应本文示例中的测试类)
🌱外观模式的实现
示例:
在计算机主机(Host)中,只需要按下主机的开机按钮,即可以调用其他硬件设备和软件的启动方法,如内存(Memory)的自检,CPU的运行,硬盘(HardDisk)的读取,操作系统(OS)的载入等,如果某一过程发生错误则计算机启动失败。使用外观模式模拟该过程,并编程实现。
思考:想象一下如果没有主机上的开关,那么电脑的其它部件都需要我们一个个手动去启动那该是一件多么困难的事情,不仅要熟练掌握每一个部件如何开启,还需要注意每一个部件的开启顺序,而使用外观模式,只需在主机上轻轻一按,电脑就能成功启动了,是不是觉得轻松多了
-
Step1:创建子系统
1)CPU:
package com.hhxy.computer; /** * @author ghp * @date 2022/10/14 * @title CPU * @description */ public class CPU { public void run(){ System.out.println("CPU运行了"); } }
2)硬盘:
package com.hhxy.computer; /** * @author ghp * @date 2022/10/14 * @title 硬盘 * @description */ public class HardDisk { public void read(){ System.out.println("硬盘开始读取数据"); } }
3)内存:
package com.hhxy.computer; /** * @author ghp * @date 2022/10/14 * @title 内存 * @description */ public class Memory { public void check(){ System.out.println("内存开始自检"); } }
4)操作系统:
package com.hhxy.computer; /** * @author ghp * @date 2022/10/14 * @title 操作系统 * @description */ public class OS { public void load(){ System.out.println("操作系统开始载入"); } }
-
Step2:创建外观类
主机:
package com.hhxy.computer; /** * @author ghp * @date 2022/10/14 * @title 主机(外观类) * @description 用于和客户进行交互,统一管理电脑硬件和软件的启动 */ public class Host { CPU cpu; HardDisk hardDisk; Memory memory; OS os; public Host(){ cpu = new CPU(); hardDisk = new HardDisk(); memory = new Memory(); os = new OS(); } /** * 开机的方法 */ public void startUp(){ cpu.run(); hardDisk.read(); memory.check(); os.load(); } }
-
Step3:编写测试类
package com.hhxy.test; import com.hhxy.computer.Host; /** * @author ghp * @date 2022/10/14 * @title 测试类2 * @description 用于模拟使用外观模式 */ public class Test2 { public static void main(String[] args) { Host host = new Host(); host.startUp(); } }
测试结果:
如果不使用外观类,就需要手动启动电脑的每一个部件:
package com.hhxy.test; import com.hhxy.computer.CPU; import com.hhxy.computer.HardDisk; import com.hhxy.computer.Memory; import com.hhxy.computer.OS; /** * @author ghp * @date 2022/10/14 * @title 测试类1 * @description 用于模拟不使用外观模式 */ public class Test1 { public static void main(String[] args) { //模拟开机 CPU cpu = new CPU(); cpu.run(); HardDisk hardDisk = new HardDisk(); hardDisk.read(); Memory memory = new Memory(); memory.check(); OS os = new OS(); os.load(); } }
🌲总结
-
总的来讲外观模式的核心就是:将复杂的东西变得简单
这里的复杂的东西从本个小案例是无法看出来的, 在实际开发中一般会是一堆复杂交错的子系统,并且外观模式的设计也是相当复杂的,从这个案例可能只是窥探其冰山一角,真真想要掌握,往往需要大量的开发经验,这篇文章也是博主首次探索外观模式,期待大家的关注,后续将持续更新设计模式相关内容,往后也会发布设计模式的深度思考和总结性的文章
-
与外观者模式相关的其它设计模式
- Singleton模式:有时会使用Singleton模式创建Facade角色
- Abstract Factory模式:可以将Abstract Factory模式看作生成复杂实例时的Facade模式。因为它提供了“要想生成这个实例只需要调用这个方法就OK了”的简单接口
- Mediator模式:在Facade模式中,Facade角色单方面地使用其他角色来提供高层接口(API)。而在Mediator模式中,Mediator角色作为Colleague角色间的仲裁者负责调停。可以说,Facade模式是单向的,而Mediator角色是双向的
自此,文章就结束了,如果觉得本文对你有一丢丢帮助的话😄,欢迎点赞👍+评论✍,您的支持将是我写出更加优秀文章的动力O(∩_∩)O
上一篇:每日一个设计模式之【装饰模式】
下一篇:每日一个设计模式之【享元模式】