手撕设计模式——智能家居平台之外观模式
1.业务需求
大家好,我是菠菜啊,好久不见,今天给大家带来的是——外观模式。老规矩,在介绍这期内容前,我们先来看看这样的需求:在智能家居平台中,用户怎么样实现场景化操作(如“回家模式”“睡眠模式”)?

2.代码实现
Talk is cheap,show me your code.
初版实现思路:
我们直接调用多个子设备,实现回家模式的场景化需求。
初版代码如下:
//家居设备基础接口
public interface HomeDevice {
String getName();
String getStatus();
}
//灯光设备
public class LightDevice implements HomeDevice{
private String name;
private int brightness=0;
public LightDevice(String name){
name = name;
}
public void dim(int level) {
brightness = level;
System.out.println("灯光调暗至 " + level + "%");
}
public void onLight(){
System.out.println("打开灯光");
brightness = 100;
}
public void offLight(){
System.out.println("关闭灯光");
brightness = 0;
}
@Override
public String getName() {
return name;
}
@Override
public String getStatus() {
return "灯光"+ brightness + "%";
}
}
//电视设备
public class TVDevice implements HomeDevice{
private String name;
private String status;
public TVDevice(String name){
name = name;
}
public void onTV(){
System.out.println("打开TV");
status = "on";
}
public void offTV(){
System.out.println("关闭TV");
status = "off";
}
@Override
public String getName() {
return name;
}
@Override
public String getStatus() {
return status;
}
}
//空调设备
public class AirCondition implements HomeDevice{
private String name;
private String status;
public AirCondition(String name){
name = name;
}
public void startCooling(){
System.out.println("空调制冷");
status = "cooling";
}
public void off() {
System.out.println("空调关机");
status = "off";
}
@Override
public String getName() {
return name;
}
@Override
public String getStatus() {
return status;
}
}
//客户端
public class Client {
public static void main(String[] args) {
LightDevice light = new LightDevice("Light");
TVDevice tv = new TVDevice("TV");
AirCondition ac = new AirCondition("AC");
System.out.println("-----------------HomeModel start-----------------");
light.onLight();
tv.onTV();
ac.startCooling();
System.out.println("-----------------HomeModel end-----------------");
}
}
执行结果:

思考:
上述代码我们也发现一些问题,如客户端(用户)切换到回家模式的时候,需要自行完成三个子设备的调用,用户需要关心这么多细节吗?这样耦合性是不是太强了?于是,我们又经过一系列优化。
3.代码优化
优化代码:
//智能家居外观类
public class SmartHomeFacade {
private LightDevice lightDevice;
private TVDevice tvDevice;
private AirCondition airCondition;
public SmartHomeFacade() {
lightDevice = new LightDevice("Light");
tvDevice = new TVDevice("TV");
airCondition = new AirCondition("AirCondition");
}
public void activeHomeModel() {
System.out.println("-----------------activeHomeModel start-----------------");
lightDevice.onLight();
tvDevice.onTV();
airCondition.startCooling();
System.out.println("-----------------activeHomeModel end-----------------");
System.out.println("deviceName:"+lightDevice.getName()+",status:"+lightDevice.getStatus());
System.out.println("deviceName:"+tvDevice.getName()+",status:"+tvDevice.getStatus());
System.out.println("deviceName:"+airCondition.getName()+",status:"+airCondition.getStatus());
}
}
//客户端
public class Client {
public static void main(String[] args) {
/* LightDevice light = new LightDevice("Light");
TVDevice tv = new TVDevice("TV");
AirCondition ac = new AirCondition("AC");
System.out.println("-----------------HomeModel start-----------------");
light.onLight();
tv.onTV();
ac.startCooling();
System.out.println("-----------------HomeModel end-----------------");*/
SmartHomeFacade smartHomeFacade = new SmartHomeFacade();
smartHomeFacade.activeHomeModel();
}
}
执行结果:

代码结构:

思考:
用户无需要知道所有设备的调用细节,只需简单调用SmartHomeFacade的activeHomeModel方法,实现真正意义上的一键切换回家模式。如果调用逻辑修改或者添加新设备了,客户端无感知,进一步降低耦合,符合迪米特法则。
4.定义与组成

定义:
外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。外观模式定义了一个高层接口,这个接口使得子系统更容易使用。
组成:
- 外观(Facade):提供统一的调用接口,将客户端请求委派给适当的子系统对象
- 子系统(SubSystem):实现具体功能,被外观类调用
核心思想
封装复杂性,提供简单接口
通过创建一个简化的高层接口,隐藏子系统的实现细节,降低客户端与子系统的耦合度。
5.代码重构(工厂模式+抽象外观模式)
思考:
上述的代码实现依赖外观类,不够抽象,而且新增家居设备需要修改外观类,而且不支持动态扩展场景,所以了解了问题后我们进一步重构了代码。
代码重构:
//抽象智能家居外观接口
public interface ISmartHomeFacade {
//切换到回家模式
void activeHomeModel();
//切换到睡眠模式
void activateSleepMode();
// 扩展点:动态添加设备
void addDevice(String deviceName, HomeDevice device);
// 获取设备
<T extends HomeDevice> T getDevice(Class<T> deviceClass);
}
//动态智能家居外观类
public class DynamicSmartHomeFacade implements ISmartHomeFacade{
private final Map<String, HomeDevice> devices = new HashMap<>();
public DynamicSmartHomeFacade() {
addDevice("Light",new LightDevice("Light"));
addDevice("TV",new TVDevice("TV"));
addDevice("AirCondition",new AirCondition("AirCondition"));
}
@Override
public void activeHomeModel() {
System.out.println("-----------------activeHomeModel start-----------------");
getDevice(LightDevice.class).onLight();
getDevice(TVDevice.class).onTV();
getDevice(AirCondition.class).startCooling();
System.out.println("-----------------activeHomeModel end-----------------");
}
// 泛型方法获取设备
@SuppressWarnings("unchecked")
public <T extends HomeDevice> T getDevice(Class<T> deviceClass) {
return devices.values().stream()
.filter(deviceClass::isInstance)
.map(device -> (T) device)
.findFirst()
.orElseThrow(() -> new RuntimeException(
"Device not found: " + deviceClass.getSimpleName()));
}
public boolean hasDevice(Class<? extends HomeDevice> deviceClass) {
return devices.values().stream()
.anyMatch(deviceClass::isInstance);
}
@Override
public void activateSleepMode() {
System.out.println("-----------------activateSleepMode start-----------------");
getDevice(LightDevice.class).dim(10);
getDevice(TVDevice.class).offTV();
getDevice(AirCondition.class).startCooling();
System.out.println("-----------------activateSleepMode end-----------------");
}
@Override
public void addDevice(String deviceName, HomeDevice device) {
devices.put(deviceName, device);
}
}
//抽象场景工厂接口
public interface ISceneFactory {
SmartHomeScene createScene();
}
//离家模式创建工厂
public class AwayHomeISceneFactory implements ISceneFactory {
@Override
public SmartHomeScene createScene() {
return new SmartHomeScene("离家模式",(facade->{
System.out.println("-----------------activeAwayHomeModel start-----------------");
facade.getDevice(LightDevice.class).offLight();
facade.getDevice(TVDevice.class).offTV();
facade.getDevice(AirCondition.class).off();
System.out.println("-----------------activeAwayHomeModel end-----------------");
}));
}
}
//场景管理
public class SceneManager {
private final Map<String, ISceneFactory> sceneFactories = new HashMap<>();
private final ISmartHomeFacade facade;
public SceneManager(ISmartHomeFacade facade) {
this.facade = facade;
}
public void registerScene(String name, ISceneFactory factory) {
sceneFactories.put(name, factory);
}
public void activateScene(String name) {
ISceneFactory factory = sceneFactories.get(name);
if(factory != null) {
SmartHomeScene scene = factory.createScene();
scene.execute(facade);
}
}
}
//动态场景类
public class SmartHomeScene {
private final String sceneName;
private final Consumer<ISmartHomeFacade> sceneExecutor;
public SmartHomeScene(String sceneName, Consumer<ISmartHomeFacade> sceneExecutor) {
this.sceneName = sceneName;
this.sceneExecutor = sceneExecutor;
}
public void execute(ISmartHomeFacade facade) {
sceneExecutor.accept(facade);
}
}
//智能床设备
public class SmartBedDevice implements HomeDevice{
private String name;
private int angle=0;
public SmartBedDevice(String name){
name = name;
}
public void adjust(int angle) {
angle = angle;
System.out.println("智能床调至 " + angle + "角度");
}
@Override
public String getName() {
return name;
}
@Override
public String getStatus() {
return "智能床"+ angle + "角度";
}
}
//客户端
public class Client2 {
public static void main(String[] args) {
DynamicSmartHomeFacade facade = new DynamicSmartHomeFacade();
// 开启回家模式
facade.activeHomeModel();
// 添加智能床设备
facade.addDevice("SmartBed", new SmartBedDevice("SmartBed"));
// 开启睡眠模式
facade.activateSleepMode();
ISceneFactory factory = new AwayHomeISceneFactory();
SceneManager sceneManager = new SceneManager(facade);
sceneManager.registerScene("离家模式", factory);
sceneManager.activateScene("离家模式");
}
}
上述代码执行结果:

实现代码结构:

总结:
上述代码通过抽象外观接口,通过addDevice()方法添加,无需修改外观类,通过SceneManager动态注册场景工厂新增场景,实现设备热插拔以及场景热部署。这种基于抽象接口的外观模式实现,不仅遵循了开闭原则,还为智能家居系统提供了强大的扩展能力。通过动态设备管理和场景工厂等机制,系统可以在不修改核心代码的情况下持续演进,完美适应快速变化的智能家居生态。
6.应用示例
其实外观模式我们在日常开发的时候应用的很广泛,下面是一些示例:
6.1日志框架:
// SLF4J是典型的外观模式实现
Logger logger = LoggerFactory.getLogger(MyClass.class);
logger.info("This is a log message");
6.2 Spring框架:
// JdbcTemplate封装了JDBC的复杂性
jdbcTemplate.query("SELECT * FROM users", new BeanPropertyRowMapper<>(User.class));
6.3 Files类
// Files类封装了文件操作的复杂性
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
7.适用场景
| 场景类型 | 是否适用 | 原因 |
|---|---|---|
| 系统复杂且模块多 | ✅ 非常适用 | 简化客户端调用 |
| 需要解耦客户端与子系统 | ✅ 推荐使用 | 降低依赖关系 |
| 需要为子系统提供统一入口 | ✅ 理想选择 | 提供简洁接口 |
| 需要逐步重构遗留系统 | ✅ 适用 | 作为中间层 |
技术需要沉淀,同样生活也是~
个人链接:博客,欢迎一起交流











This is a fantastic breakdown of the Facade pattern. The smart home analogy perfectly illustrates how complex backend systems (multiple devices) can be abstracted into a simple, user-friendly interface (“Home Mode”). This principle of simplification is crucial in all digital product design, whether it’s managing device states or accessing a robust platform like the one available via kingjl app download. Great deep dive!
This is a perfect illustration of abstraction. The Facade pattern, simplifying complex device interactions into simple “scenes,” mirrors how excellent UX is vital across all tech. Whether managing smart homes or accessing sophisticated betting markets, the goal is always a seamless interface. For reliable, simplified access to high-engagement platforms, check out the okpun app download apk. Great deep dive!
The UI flow seems solid, but for absolute beginners, simplifying the initial steps after viewing the queencasino apk guide would boost UX. Great job capturing that classic feel!