外观模式

介绍

**定义:**通过为多个复杂的子系统提供一个一致的接口, 使这些子系统更加容易被访问. 由于该模式有一个对外的统一接口, 所以外部程序无需关注子系统的内部细节, 从而大大降低了应用程序的复杂度, 提高了程序的可维护性.

UML

示例

java 复制代码
package com.sumlv.demo;

import com.sumlv.demo.facade.SmartSpeakerFacade;

public class Main {

    public static void main(String[] args) {
        SmartSpeakerFacade facade = new SmartSpeakerFacade();
        facade.doCommand("打开电视");
    }

}
java 复制代码
package com.sumlv.demo.facade;

import com.sumlv.demo.service.AirConditioner;
import com.sumlv.demo.service.Light;
import com.sumlv.demo.service.TV;

/**
 * 智能音箱外观(外观类)
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-16
 */
public class SmartSpeakerFacade {

    private AirConditioner airConditioner;

    private Light light;

    private TV tv;

    public SmartSpeakerFacade() {
        this.airConditioner = new AirConditioner();
        this.light = new Light();
        this.tv = new TV();
    }

    public void doCommand(String message) {
        if (message.contains("打开")) {
            this.on(message);
        }

        if (message.contains("关闭")) {
            this.off(message);
        }
    }

    private void off(String message) {
        if (message.contains("空调")) {
            this.airConditioner.off();
        }

        if (message.contains("灯光")) {
            this.light.off();
        }

        if (message.contains("电视")) {
            this.tv.off();
        }
    }

    private void on(String message) {
        if (message.contains("空调")) {
            this.airConditioner.on();
        }

        if (message.contains("灯光")) {
            this.light.on();
        }

        if (message.contains("电视")) {
            this.tv.on();
        }
    }

}
java 复制代码
package com.sumlv.demo.service;

/**
 * 电视(子系统A)
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-16
 */
public class TV {

    public void on() {
        System.out.println("电视已打开");
    }

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

}
java 复制代码
package com.sumlv.demo.service;

/**
 * 空调(子系统B)
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-16
 */
public class AirConditioner {

    public void on() {
        System.out.println("空调已打开");
    }

    public void off() {
        System.out.println("空调已关闭");
    }

}
java 复制代码
package com.sumlv.demo.service;

/**
 * 电灯(子系统C)
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-16
 */
public class Light {

    public void on() {
        System.out.println("电灯已打开");
    }

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

}

总结

使用场景

  1. 需要简化复杂系统时(当某些业务需要对当前系统内多个子系统进行调用时, 就可以根据不同业务场景为调用方提供对应的门面);

  2. 需要隐藏内部实现细节时(如把大象装进冰箱总共需要3步, 当不希望调用方知道具体如何实现时, 就可以只对外提供一个装进冰箱的门面而非3步对应的3个接口).

优点:

  1. 由于客户端无需直接调用子系统, 所以会使客户端的代码更加简洁;

  2. 引入外观类的方式轻松实现了客户端与众多子系统之间的解耦.

缺点:

  1. 降低了系统灵活性(由于客户端无法直接访问子系统, 当业务发生变更时就无法灵活的调整子系统的调用顺序, 也无法灵活添加/移除子系统);

  2. 如果设计不当, 当子系统发生变化时可能会导致外观类的同步修改, 违背了开闭原则.

相关推荐
sg_knight6 天前
外观模式(Facade)
开发语言·python·外观模式·facade
JTCC6 天前
Java 设计模式西游篇 - 第九回:外观模式简化繁 如来神掌一指定
java·设计模式·外观模式
oOOpHQYUKG1 个月前
COMSOL激光淬火相变模拟
外观模式
白太岁1 个月前
Redis:(3) Lua 与 Redis、基于连接池的 Facade 模式封装
数据库·c++·redis·lua·外观模式
SHeqSpMeS1 个月前
PID 和 LQR 主动悬架模型对比:探索汽车平顺性的优化之路
外观模式
懵萌长颈鹿1 个月前
外观模式 (Facade Pattern)
外观模式
wVAkMDmzEWcm1 个月前
易语言实现Jlink烧录程序:打造自动化烧录利器
外观模式
蔺太微2 个月前
外观模式(Facade Pattern)
设计模式·外观模式
小码过河.2 个月前
设计模式——外观模式
设计模式·外观模式