设计模式 六月 03, 2021

门面模式

文章字数 3.3k 阅读约需 3 mins. 阅读次数 0

门面模式

解决问题

想要办理一些业务的时候,由于程序复杂,需要跑很多地方才能完成一项业务.这时候就想着能不能有个统一的窗口,能按照流程帮我办理好这些业务.这也是政府当下推广的”最多跑一次”服务.

方案

提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使用子系统更容易使用。

结构

门面模式

  • 门面角色:客户端调用这个角色的方法。此角色知晓相关的子系统的功能和责任。正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统中去。

  • 子系统角色:可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色直接调用。子系统并不知道门面的存在,罪域子系统而言,门面仅仅是另一个客户端而已。

适用性

与中介模式相类似,但门面模式更侧重于服务与客户的交流.

  • 简化子系统复杂性时。
  • 监控所有子系统时;通过门面控制了入口,可以统一监控;
  • 希望封装和隐藏子系统时;
  • 两历史系统进行改造并打通关系时;

优缺点

优点

  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入门面模式,客户代码将变得很简单,与之关联的对象也很少。
  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
  • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

经典实现

如今很火的全屋智能总控开关.

// 灯系统
public class Light {
    public void open(){
        System.out.println("Light has been opened!");
    }
}

// 空调系统
public class AirConditioning {
    public void open(){
        System.out.println("AirConditioning has been opened!");
    }
}

// 电视系统
public class TV {
    public void open(){
        System.out.println("TV has been opened!");
    }
}

// 中央控制器. 
public class Facade {

    private Light light1, light2, light3;
    private AirConditioning airConditioning, AirConditioning airConditioning2;
    private TV tv;

    // 收集满足场景的设备
    public Facade() {
        light1 = new Light();
        light2 = new Light();
        light3 = new Light();
        airConditioning = new AirConditioning();
        airConditioning2 = new AirConditioning();
        tv = new TV();
    }
    // 观影模式,开启客厅的灯,空调与电视.
    public void viewingMode() {
        light1.open();
        light2.open();
        airConditioning.open();
        tv.open();
    }
    // 睡眠模式,开启卧室的灯与空调
    public void sleep(){
        light3.open();
        airConditioning2.open();
    }
}


public class Demo {
     public static void main(String[] args) {
        Facade zhihuishenghuo = new Facade();
        /**
         * 一步操作就可以完成所有的准备工作
         */
        zhihuishenghuo.viewingMode();
    }
}







0%