把书读薄 | 《设计模式之美》设计模式与范式(结构型-门面模式)

简介: 本文对应设计模式与范式:结构型(52),门面模式 (Facada Pattern),又称 外观模式。了解定义,适用场景、优缺点和使用示例就差不多了~

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 (子系统) → 子系统不知道门面的存在,对于它而言,门面仅仅是另外一个客户端而已;


门面模式通过引入一个外观角色来简化客户端与子系统间的交互,为复杂子系统的调用提供一个统一的入口,使得子系统与客户端的耦合度降低,客户端调用方便。


门面模式并不会给系统增加任何新功能,仅仅是 简化调用,统一操作,当然也有缺点:降低了可靠性,过多子系统同依赖一个门面系统,门面系统挂了可能导致子系统无法使用;子系统扩展升级没通知门面系统,可能会造成系统的不可用。


使用场景


  • 解决易用性问题;


  • 解决性能问题; (客户端访问服务需调用多个接口,外观模式简化一波)


  • 解决分布式事务问题;


  • 作为一个简洁的中间层,联合更多系统来扩展原有系统;


相关文章
|
7月前
|
设计模式 程序员
结构型设计模式之适配器模式
结构型设计模式之适配器模式
|
7月前
|
设计模式
结构型设计模式之装饰模式
结构型设计模式之装饰模式
|
7月前
|
设计模式 编解码 网络安全
结构型设计模式之代理模式
结构型设计模式之代理模式
|
8月前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~结构型]不兼容结构的协调——适配器模式
[设计模式Java实现附plantuml源码~结构型]不兼容结构的协调——适配器模式
|
8月前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
|
8月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型] 扩展系统功能——装饰模式
[设计模式Java实现附plantuml源码~结构型] 扩展系统功能——装饰模式
|
8月前
|
设计模式 存储 缓存
第三篇 结构型设计模式 - 简化复杂系统的结构
第三篇 结构型设计模式 - 简化复杂系统的结构
|
8月前
|
设计模式 存储 Java
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
|
8月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型]处理多维度变化——桥接模式
[设计模式Java实现附plantuml源码~结构型]处理多维度变化——桥接模式
|
8月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式
[设计模式Java实现附plantuml源码~结构型]对象的间接访问——代理模式

热门文章

最新文章