介绍
**定义:**通过为多个复杂的子系统提供一个一致的接口, 使这些子系统更加容易被访问. 由于该模式有一个对外的统一接口, 所以外部程序无需关注子系统的内部细节, 从而大大降低了应用程序的复杂度, 提高了程序的可维护性.
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("电灯已关闭");
}
}
总结
使用场景
-
需要简化复杂系统时(当某些业务需要对当前系统内多个子系统进行调用时, 就可以根据不同业务场景为调用方提供对应的门面);
-
需要隐藏内部实现细节时(如把大象装进冰箱总共需要3步, 当不希望调用方知道具体如何实现时, 就可以只对外提供一个装进冰箱的门面而非3步对应的3个接口).
优点:
-
由于客户端无需直接调用子系统, 所以会使客户端的代码更加简洁;
-
引入外观类的方式轻松实现了客户端与众多子系统之间的解耦.
缺点:
-
降低了系统灵活性(由于客户端无法直接访问子系统, 当业务发生变更时就无法灵活的调整子系统的调用顺序, 也无法灵活添加/移除子系统);
-
如果设计不当, 当子系统发生变化时可能会导致外观类的同步修改, 违背了开闭原则.