门面设计模式

github:GitHub - QiuliangLee/pattern: 设计模式

1 什么是门面设计模式

门面设计模式是一种软件设计模式,也被称为外观(Facade)模式。它提供了一个简单的接口,让客户端能够访问复杂系统中的一组接口。通过门面模式,我们可以隐藏系统的复杂性,并提供一个简单的接口来访问系统。此外,门面模式还可以帮助我们解耦系统中的各个模块,从而提高系统的可维护性和可测试性。

增加一层

提供一个高层次的接口,使得子系统更易于使用

2 为什么需要门面设计模式

需求:电商场景下,需要各个模块的汇总报表,这里只写了三个,真实场景下很多。

java 复制代码
//订单系统
public class OrderSys {
    public String getOrderNum(){
        System.out.println("获取订单号");
        return "123456";
    }
}
//支付系统
public class PaymentSys {
    private OrderSys orderSys;
    public PaymentSys(OrderSys orderSys) {
        this.orderSys = orderSys;
    }
    public BigDecimal getOrderAccount(String orderNum){
        System.out.println(String.format("获取%s订单支付金额",orderNum));
        return BigDecimal.valueOf(500);
    }
}
//物流系统
public class DeliverySys {
    public int getDeliveryTime(){
        System.out.println("获取配送耗时");
        return 30*60;//30分钟
    }
}
复制代码
client
java 复制代码
package com.lql.facade;

public class Client {
    public static void main(String[] args) {
        OrderSys orderSys = new OrderSys();
        PaymentSys paymentSys = new PaymentSys(orderSys);
        DeliverySys deliverySys = new DeliverySys();

        final String orderNum = orderSys.getOrderNum();
        System.out.println(String.format("\n报表\n--------------------------------------------\n" +
                        "订单号:%s | 金额:%s元 | 配送耗时:%s分钟",
                orderNum,
                paymentSys.getOrderAccount(orderNum).toPlainString(),
                deliverySys.getDeliveryTime() / 60)
        );
    }
}

缺点:

1.客户端难以使用:如果系统中有很多复杂的子系统,客户端就需要了解每一个子系统的实现细节,这会增加客户端的使用难度和学习成本。

比如我要是想使用报表服务,就需要知道订单服务,物流服务,支付服务等等。

2.系统之间的耦合度高:如果子系统的实现发生变化,客户端也需要相应地修改自己的代码来适应变化,这会增加系统之间的耦合度,降低系统的灵活性和可维护性。

订单服务,物流服务,支付服务任何一个服务改变,我这里的报表服务就要改代码,

3.代码冗余:如果多个客户端都需要访问同一个子系统,那么每个客户端都需要编写相同的代码来访问该子系统,这会增加代码冗余和维护成本。

3. 门面模式

复制代码
ReportFacade
java 复制代码
package com.lql.facade;

public class ReportFacade {
    public void generateReport() {
        OrderSys orderSys = new OrderSys();
        PaymentSys paymentSys = new PaymentSys(orderSys);
        DeliverySys deliverySys = new DeliverySys();

        final String orderNum = orderSys.getOrderNum();
        System.out.println(String.format("\n报表\n--------------------------------------------\n" +
                        "订单号:%s | 金额:%s元 | 配送耗时:%s分钟",
                orderNum,
                paymentSys.getOrderAccount(orderNum).toPlainString(),
                String.valueOf(deliverySys.getDeliveryTime() / 60))
        );
    }
}
复制代码
Client
java 复制代码
package com.lql.facade;

public class Client {
    public static void main(String[] args) {
        ReportFacade reportFacade = new ReportFacade();
        reportFacade.generateReport();
    }
}

4. 应用场景

  1. DDD中apliication层用来编排各个domain service的接口就是借鉴了门面设计思想。

  2. MyBatis 中的Configuration 去创建MetaObject 对象使用到外观模式

相关推荐
kkkkkkkkl24几秒前
Spring Boot 中基于线程池的订单创建并行化实践
java·spring boot·juc
lly2024061 分钟前
Julia 的复数和有理数
开发语言
春日见2 分钟前
如何提升手眼标定精度?
linux·运维·开发语言·数码相机·matlab
廋到被风吹走4 分钟前
【Spring】ThreadLocal详解 线程隔离的魔法与陷阱
java·spring·wpf
星辰离彬4 分钟前
2025 IDEA运行报错:运行 xxxxApplication 时出错。命令行过长。 通过 JAR 清单或通过类路径文件缩短命令行,然后重新运行。
java·后端·intellij-idea·jar
古城小栈7 分钟前
Java 响应式编程:Spring WebFlux+Reactor 实战
java·开发语言·spring
攻心的子乐9 分钟前
sentinel使用指南 限流/熔断 微服务 ruoyi-cloud使用了
java·开发语言
zsyy@10 分钟前
Maven本地仓库有jar还会向远程仓库下载依赖的问题
java·服务器·maven
点云SLAM11 分钟前
C++ 偏特化详解
开发语言·c++·c++模板·c++17·c++高级应用·c++偏特化·大型项目
wregjru11 分钟前
【C++】2.3 二叉搜索树的实现(附代码)
开发语言·前端·javascript