(结构型模式)外观模式

76 阅读3分钟

简介

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

角色

  • Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统,传递给相应的子系统对象处理。
  • SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
  • Client(客户角色):通过一个外观角色访问各个子系统的功能

使用场景

  • 当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式。

  • 客户程序与抽象类的实现部分之间存在着很大依赖性(分离逻辑,提高子系统的独立性和可移植性)

具体案例

假如我们每天起床的步骤是打开电视,打开空调,打开窗户;睡觉前的步骤是关闭电视,关闭空调,关闭窗户。
外观模式的核心在于为系统提供统一的子接口,封装子系统的复杂性,便于客户调用。也就说将这三件事情封装在一起。

子系统

//电视
public class Tv {
    
    public void open(){
        System.out.println("打开了电视");
    }
    
    public void close(){
        System.out.println("关闭了电视");
    }
}
//空调
public class AirConditioner {
    
    public void open(){
        System.out.println("打开了空调");
    }

    public void close(){
        System.out.println("关闭了空调");
    }
    
}
//窗户
public class Window {

    public void open(){
        System.out.println("打开了窗户");
    }

    public void close(){
        System.out.println("关闭了窗户");
    }

}

外观类

//Ai助手
public class AiAssistant {

    /**
     * 一键开启
     */
    public void open(){
        Tv tv = new Tv();
        AirConditioner airConditioner = new AirConditioner();
        Window window = new Window();
        tv.open();
        airConditioner.open();
        window.open();
    }

    /**
     * 一键关闭
     */
    public void close(){
        Tv tv = new Tv();
        AirConditioner airConditioner = new AirConditioner();
        Window window = new Window();
        tv.close();
        airConditioner.close();
        window.close();
    }
    
}

测试

public class Demo {

    public static void main(String[] args) {
        AiAssistant aiAssistant = new AiAssistant();
        System.out.println("起床了---");
        aiAssistant.open();
        System.out.println("睡觉---");
        aiAssistant.close();
    }
}

LR7WEdyLmp.jpg

外观模式优缺点

优点

  • 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
  • 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。

缺点

  • 如果增加新的子系统可能需要修改外观类或客户端的源代码,这样就违背了开闭原则。