0x0、引言
?页面写完,等后端接口联调,继续啃《设计模式之美》,本文对应设计模式与范式:结构型(52),门面模式
(Facada Pattern),又称 外观模式。
了解定义,适用场景、优缺点和使用示例就差不多了~
Tips:二手知识加工难免有所纰漏,感兴趣有时间的可自行查阅原文,谢谢。
0x1、定义
为子系统提供一组统一的接口,定义一个更高层接口让子系统更易用。
从定义可以看出门面模式的本质就是 统一多个接口的功能
,简化外部系统使用内部多个子系统的使用方式。
举个形象的例子:电表箱
主卧、餐厅、阳台等可以看做是 子系统,而电表箱就是 更高层的接口,通过电表箱可以对每个子系统进行电源控制。
而扩展到实际开发中的例子:
A系统提供a、b、c、d四个接口,B系统完成某个功能,要调用A系统的a、b、d接口,利用门面模式,我们可以提供一个包裹了a、b、d接口调用的门面接口x供系统B直接使用。
这样做的好处:B不用调三次接口,提高了响应速度,更易用;
- 如果门面接口不多,完全可以跟非门面接口放在一块,也不需要特殊标记,当作普通接口来用就好;
- 如果门面接口很多,可以在已有接口之上,重新抽象出一层,专门放置门面接口,从类、包命名上与原接口层做区分;
- 如果门面接口特别多,且很多都是跨多个子系统的,可以将门面接口放到一个新的子系统中;
和代理模式最根本的不同:门面模式可能代理多个接口,而代理模式通常只是代理某个接口;
0x2、写个简单例子
以上面的电表箱为例子写下代码吧:
// 子系统角色
public class Bedroom {
public void powerOff() { System.out.println("断开卧室供电"); }
public void powerOn() { System.out.println("打开卧室供电"); }
}
public class Restaurant {
public void powerOff() { System.out.println("断开厨房供电"); }
public void powerOn() { System.out.println("打开厨房供电"); }
}
public class Balcony {
public void powerOff() { System.out.println("断开阳台供电"); }
public void powerOn() { System.out.println("打开阳台供电"); }
}
// 门面角色
public class ElectricBox {
private Bedroom bedroom;
private Restaurant restaurant;
private Balcony balcony;
public ElectricBox(Bedroom bedroom, Restaurant restaurant, Balcony balcony) {
this.bedroom = bedroom;
this.restaurant = restaurant;
this.balcony = balcony;
}
public void powerOnAll() {
System.out.println("=== 打开所有供电=== ");
bedroom.powerOn();
restaurant.powerOn();
balcony.powerOn();
}
public void powerOffAll() {
System.out.println("=== 断开所有供电 === ");
bedroom.powerOff();
restaurant.powerOff();
balcony.powerOff();
}
public void bedroomPowerOn() {
System.out.println("=== 打开卧室供电 === ");
bedroom.powerOn();
}
}
// 测试用例
public class FacadeTest {
public static void main(String[] args) {
ElectricBox box = new ElectricBox(new Bedroom(), new Restaurant(), new Balcony());
box.powerOnAll();
box.powerOffAll();
box.bedroomPowerOn();
}
}
复制代码
运行结果输出如下:
顺手画下UML类图和介绍下两个角色:
- Facade (门面角色) → 负责处理子系统调用逻辑,一般没有实际的具体业务,只是一个委托类;
- SubSystem (子系统) → 子系统不知道门面的存在,对于它而言,门面仅仅是另外一个客户端而已;
门面模式通过引入一个外观角色来简化客户端与子系统间的交互,为复杂子系统的调用提供一个统一的入口,使得子系统与客户端的耦合度降低,客户端调用方便。
门面模式并不会给系统增加任何新功能,仅仅是 简化调用,统一操作
,当然也有缺点:降低了可靠性,过多子系统同依赖一个门面系统,门面系统挂了可能导致子系统无法使用;子系统扩展升级没通知门面系统,可能会造成系统的不可用。
使用场景
-
解决易用性问题;
-
解决性能问题; (客户端访问服务需调用多个接口,外观模式简化一波)
-
解决分布式事务问题;
-
作为一个简洁的中间层,联合更多系统来扩展原有系统;