0
点赞
收藏
分享

微信扫一扫

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

624c95384278 2022-03-11 阅读 22
外观模式

        外观模式也叫门面模式(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("我回家了");
    }
}

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

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

举报

相关推荐

0 条评论