设计模式|Java设计模式-外观模式

我又来了,继Java设计模式之桥接模式后,现在来到了外观模式啦,外观模式又称为门面模式啦,下面慢慢来啦。
设计模式|Java设计模式-外观模式
文章图片

一张旧图,恍惚间念起旧人

Java设计模式-外观模式
    • 一、前言
      • 1)引入:
      • 2)概述:
      • 3)角色结构:
      • 4)使用场景
    • 二、案例
      • 代码:
    • 三、总结
      • 优点:
      • 缺点:
    • 四、自言自语

一、前言 1)引入:
在以前,手机没有这么方便的时候,我们一旦需要去哪里哪里办个什么证,那真就的从这签个字从那签个字,签一路,才能办下那个证,
比如去办房产证:
设计模式|Java设计模式-外观模式
文章图片

作为懒人的我们,肯定会想要是能有个一站式的就好了。直接一次解决所有问题。
其实,在我们软件设计当中,也是如此。当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
2)概述:
【设计模式|Java设计模式-外观模式】外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式是“迪米特法则”的典型应用。
迪米特法则:又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。
3)角色结构:
主要包含以下主要角色。
  1. 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
  3. 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
设计模式|Java设计模式-外观模式
文章图片

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,实际中并不全是一样的,设计模式也是根据实际的软件设计需求来进行应用的,多数情况下都是几种设计模式一起用的。
三、总结 优点:
  1. 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  2. 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
  3. 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
缺点:
  1. 不能很好地限制客户使用子系统类,很容易带来未知风险。
  2. 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
  3. 不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
四、自言自语 你卷我卷,大家卷,什么时候这条路才是个头啊。(还是直接上天吧)
有时候也想停下来歇一歇,一直做一个事情,感觉挺难坚持的。
你好,如果你正巧看到这篇文章,并且觉得对你有益的话,就给个赞吧,让我感受一下分享的喜悦吧,蟹蟹。
如若有写的有误的地方,也请大家不啬赐教!!
同样如若有存在疑惑的地方,请留言或私信,定会在第一时间回复你。
持续更新中

    推荐阅读