Java设计模式-外观模式

911 阅读7分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

我又来了,继Java设计模式之桥接模式后,现在来到了外观模式啦,外观模式又称为门面模式啦😁,下面慢慢来啦。 会了就当复习丫,不会来一起来看看吧。

很喜欢一句话:“八小时内谋生活,八小时外谋发展”

如果你也喜欢,让我们一起坚持吧!!

共勉😁

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

设计模式系列

一、前言

1)引入:

在以前,手机没有这么方便的时候,我们一旦需要去哪里哪里办个什么证,那真就的从这签个字从那签个字,签一路,才能办下那个证,

比如去办房产证:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vbHf1WGj-1628694563882)(C:\Users\ASUS\Desktop\宁在春的学习笔记\JDK8\文档\Java设计模式-外观模式.assets\image-20210811223659159.png)]

作为懒人的我们,肯定会想要是能有个一站式的就好了。直接一次解决所有问题。

其实,在我们软件设计当中,也是如此。当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。

2)概述:

外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

外观(Facade)模式是“迪米特法则”的典型应用。

迪米特法则:又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。

3)角色结构:

主要包含以下主要角色。

  1. 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
  3. 客户(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,实际中并不全是一样的,设计模式也是根据实际的软件设计需求来进行应用的,多数情况下都是几种设计模式一起用的。

三、总结

优点:

  1. 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  2. 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
  3. 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

缺点:

  1. 不能很好地限制客户使用子系统类,很容易带来未知风险。
  2. 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
  3. 不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

四、自言自语

你卷我卷,大家卷,什么时候这条路才是个头啊。😇(还是直接上天吧)

有时候也想停下来歇一歇,一直做一个事情,感觉挺难坚持的。😁

你好,如果你正巧看到这篇文章,并且觉得对你有益的话,就给个赞吧,让我感受一下分享的喜悦吧,蟹蟹。🤗

如若有写的有误的地方,也请大家不啬赐教!!

同样如若有存在疑惑的地方,请留言或私信,定会在第一时间回复你。

持续更新中