《设计模式入门》 10.外观模式

本文通过一个模拟场景展示了外观模式(门面模式)如何应用于智能家居控制,以小爱同学作为门面角色整合风扇、灯和电视等设备的控制,降低了用户操作复杂性,提高了系统易用性。当系统设备或操作变化时,通过修改门面角色即可,但这也可能违反开闭原则。
摘要由CSDN通过智能技术生成

        外观模式也叫门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式又称为外观模式,它是一种对象结构型模式。

        简单来说就是隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口,让客户可以更简单的使用这个系统。

这个模式中,一般存在3个角色。

  1. 门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。(客户调用,同时自身调用子系统功能)
  2. 子系统角色: 实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。(实现具体功能)
  3. 客户角色: 通过调用Facede来完成要实现的功能(调用门面角色)。

=========================================================================

我们来模拟一个小爱同学进行米家集成控制的场景:

我们假设家里有三个米家设备,风扇,灯和电视,也就是门面角色:

风扇:

package FacadePattern.MiHomeProducts;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName MiFan.java
 * @Description 小米风扇
 * @createTime 2022年03月04日 14:49:00
 */
public class MiFan {
    public void turnOn(){
        System.out.println("风扇打开了");
    }

    public void turnOff(){
        System.out.println("风扇关闭了");
    }
}

电灯:

package FacadePattern.MiHomeProducts;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName MiLight.java
 * @Description 小米电灯
 * @createTime 2022年03月04日 14:49:00
 */
public class MiLight {
    public void turnOn(){
        System.out.println("电灯打开了");
    }

    public void turnOff(){
        System.out.println("电灯关闭了");
    }
}

电视:

package FacadePattern.MiHomeProducts;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName MiTv.java
 * @Description 小米电视
 * @createTime 2022年03月04日 14:48:00
 */
public class MiTv {
    public void turnOn(){
        System.out.println("电视打开了");
    }

    public void turnOff(){
        System.out.println("电视关闭了");
    }
}

如果我们回家要一个一个的打开,就会很麻烦:

模拟客户角色测试一下:

package FacadePattern;

import FacadePattern.MiHomeProducts.MiFan;
import FacadePattern.MiHomeProducts.MiLight;
import FacadePattern.MiHomeProducts.MiTv;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName FacedPatternTest.java
 * @Description FacadePatternTest
 * @createTime 2022年03月04日 15:02:00
 */
public class FacadePatternTest {
    public static void main(String[] args) {
        MiFan miFan = new MiFan();
        MiTv miTv = new MiTv();
        MiLight miLight = new MiLight();

        miFan.turnOn();
        miLight.turnOn();
        miTv.turnOn();

    }
}

        可以看到,我们需要一个个去新建对象,然后执行方法,假设我们有n个设备,对设备进行m种操作,我们就需要新建n个对象,调用m次方法,这对于客户角色是非常不友好的。

        那么我们要是使用小爱同学,把功能集成到小爱同学里面去,就会方便很多:

门面角色小爱:

package FacadePattern;

import FacadePattern.MiHomeProducts.MiFan;
import FacadePattern.MiHomeProducts.MiLight;
import FacadePattern.MiHomeProducts.MiTv;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName MiAi.java
 * @Description 小爱同学
 * @createTime 2022年03月04日 14:54:00
 */
public class MiAi {
    private MiLight miLight;
    private MiTv miTv;
    private MiFan miFan;

    public MiAi(){
        miLight = new MiLight();
        miTv = new MiTv();
        miFan = new MiFan();
    }


    public void open(String common){
        if ("我回家了".equals(common)) {
            miFan.turnOn();
            miLight.turnOn();
            miTv.turnOn();
        }else {
            System.out.println("我还不会这项技能");
        }
    }

}

        我们把创建对象和调用功能集成到了小爱的open方法中,对客户角色暴露的接口只有open,所以客户角色只需要调用他就可以了

再测一下:

package FacadePattern;

import FacadePattern.MiHomeProducts.MiFan;
import FacadePattern.MiHomeProducts.MiLight;
import FacadePattern.MiHomeProducts.MiTv;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName FacedPatternTest.java
 * @Description FacadePatternTest
 * @createTime 2022年03月04日 15:02:00
 */
public class FacadePatternTest {
    public static void main(String[] args) {
        MiFan miFan = new MiFan();
        MiTv miTv = new MiTv();
        MiLight miLight = new MiLight();

        miFan.turnOn();
        miLight.turnOn();
        miTv.turnOn();
        System.out.println("\n+++++++小爱调用++++++++\n");
        MiAi miAi = new MiAi();
        miAi.open("我回家了");
    }
}

        可以看到,一般我们遇到一个复杂子系统的调用的时候,我们可以使用外观模式来提供一个接口来降低用户使用的复杂度,并且可以在层次化结构中,使用外观模式降低层与层之间的耦合度。

        外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PigeonEssence

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值