我又来了,继Java设计模式之桥接模式后,现在来到了外观模式啦,外观模式又称为门面模式啦😁,下面慢慢来啦。 会了就当复习丫,不会来一起来看看吧。
很喜欢一句话:
“八小时内谋生活,八小时外谋发展”
。如果你也喜欢,让我们一起坚持吧!!
共勉
😁
一张旧图,恍惚间念起旧人
设计模式系列:
一、前言
1)引入:
在以前,手机没有这么方便的时候,我们一旦需要去哪里哪里办个什么证,那真就的从这签个字从那签个字,签一路,才能办下那个证,
比如去办房产证:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vbHf1WGj-1628694563882)(C:\Users\ASUS\Desktop\宁在春的学习笔记\JDK8\文档\Java设计模式-外观模式.assets\image-20210811223659159.png)]
作为懒人的我们,肯定会想要是能有个一站式的就好了。直接一次解决所有问题。
其实,在我们软件设计当中,也是如此。当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
2)概述:
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式是“迪米特法则”的典型应用。
迪米特法则:又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。
3)角色结构:
主要包含以下主要角色。
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVhuh6Og-1628694563885)(C:\Users\ASUS\Desktop\宁在春的学习笔记\JDK8\文档\Java设计模式-外观模式.assets\image-20210811224537663.png)]
4)使用场景
(1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。(例如:我们平时开发时,controller调用service接口,而不用管serviceImpl的实现是如何的,即三层开发模式。)
(2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
(3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。
二、案例
【例】智能家电控制
父母年纪大了,平时是我在家的话,这开灯开电视开空调都是父母直接喊我来做的,想着自己离开家了,父母的自己动手,就给父母买了个智能音箱来控制这些。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1F81uxz-1628694563887)(C:\Users\ASUS\Desktop\宁在春的学习笔记\JDK8\文档\Java设计模式-外观模式.assets\外观模式.png)]
代码:
电视类
public class TV { public void on() { System.out.println("打开了电视...."); } public void off() { System.out.println("关闭了电视...."); } }
灯类
public class Light { public void on() { System.out.println("打开了灯...."); } public void off() { System.out.println("关闭了灯...."); } }
空调类
public class AirCondition { public void on() { System.out.println("打开了空调...."); } public void off() { System.out.println("关闭了空调...."); } }
智能音箱
package com.crush.facade; //智能音箱 public class SmartAppliancesFacade { private Light light; private TV tv; private AirCondition airCondition; public SmartAppliancesFacade() { light = new Light(); tv = new TV(); airCondition = new AirCondition(); } public void say(String message) { if (message.contains("开灯")) { onLamp(); } else if (message.contains("关灯")) { offLamp(); } else if (message.contains("开电视")) { onTV(); } else if (message.contains("关电视")) { offTV(); } else if (message.contains("开空调")) { onAirCondition(); } else if (message.contains("关空调")) { offAirCondition(); } else { System.out.println("我还听不懂你说的!!!"); } } private void onLamp() { light.on(); } private void offLamp() { light.off(); } private void onTV() { tv.on(); } private void offTV() { tv.off(); } private void onAirCondition() { airCondition.on(); } private void offAirCondition() { airCondition.off(); } }
测试:
//测试类 public class Client { public static void main(String[] args) { //创建外观对象 SmartAppliancesFacade facade = new SmartAppliancesFacade(); //客户端直接与外观对象进行交互 facade.say("打开家电"); facade.say("关闭家电"); } }
这样就做到了通过一个智能音箱控制全部,而不用管其他的具体实现,只要知道这个接口即可以了。
当然这只是一个体现的外观模式的小demo,实际中并不全是一样的,设计模式也是根据实际的软件设计需求来进行应用的,多数情况下都是几种设计模式一起用的。
三、总结
优点:
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
- 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
- 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
缺点:
- 不能很好地限制客户使用子系统类,很容易带来未知风险。
- 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
- 不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
四、自言自语
你卷我卷,大家卷,什么时候这条路才是个头啊。😇(还是直接上天吧)
有时候也想停下来歇一歇,一直做一个事情,感觉挺难坚持的。😁
你好,如果你正巧看到这篇文章,并且觉得对你有益的话,就给个赞吧,让我感受一下分享的喜悦吧,蟹蟹。🤗
如若有写的有误的地方,也请大家不啬赐教!!
同样如若有存在疑惑的地方,请留言或私信,定会在第一时间回复你。
持续更新中