我又来了,继Java设计模式之桥接模式后,现在来到了外观模式啦,外观模式又称为门面模式啦,下面慢慢来啦。
文章图片
一张旧图,恍惚间念起旧人
Java设计模式-外观模式
-
- 一、前言
-
- 1)引入:
- 2)概述:
- 3)角色结构:
- 4)使用场景
- 二、案例
-
- 代码:
- 三、总结
-
- 优点:
- 缺点:
- 四、自言自语
一、前言 1)引入:
在以前,手机没有这么方便的时候,我们一旦需要去哪里哪里办个什么证,那真就的从这签个字从那签个字,签一路,才能办下那个证,
比如去办房产证:
文章图片
作为懒人的我们,肯定会想要是能有个一站式的就好了。直接一次解决所有问题。
其实,在我们软件设计当中,也是如此。当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
2)概述:
【设计模式|Java设计模式-外观模式】外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式是“迪米特法则”的典型应用。
迪米特法则:又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。
3)角色结构:
主要包含以下主要角色。
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
文章图片
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,实际中并不全是一样的,设计模式也是根据实际的软件设计需求来进行应用的,多数情况下都是几种设计模式一起用的。
三、总结 优点:
- 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
- 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
- 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
- 不能很好地限制客户使用子系统类,很容易带来未知风险。
- 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
- 不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
有时候也想停下来歇一歇,一直做一个事情,感觉挺难坚持的。
你好,如果你正巧看到这篇文章,并且觉得对你有益的话,就给个赞吧,让我感受一下分享的喜悦吧,蟹蟹。
如若有写的有误的地方,也请大家不啬赐教!!
同样如若有存在疑惑的地方,请留言或私信,定会在第一时间回复你。
持续更新中
推荐阅读
- 深度学习&神经网络|Transformer解析与tensorflow代码解读
- 微软相关|C#的架构、框架、设计模式
- 微信小程序|毕业论文-基于微信小程序的图书馆管理系统设计与实现
- 微信小程序|微信小程序健康预约检查管理系统的开发与实现
- springBoot|SpringBoot中Excel的上传
- Java专题|【在线实习】推推项目课程介绍—小说更新就通知
- Android|2022年中高级 Android 大厂面试秘籍,为你保驾护航金九银十,直通大厂
- 后端|2022 年最新 Java 后端薪资统计出炉,看看你有没有拖后腿
- 前端|idea如何运行Java Web项目(Servlet、JSP)