门面设计模式

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 对象使用到外观模式

相关推荐
lilian2335 分钟前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_9557596211 分钟前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
夜雪一千32 分钟前
Python从HTML提取纯文本、去空格、比对内容是否变化:方案+合理性分析
开发语言·python·html
烂蜻蜓38 分钟前
Node.js入门教程(一):初识Node.js——服务端JavaScript的诞生与特点
开发语言·javascript·node.js
雾喔1 小时前
算法练习7
java·数据结构·算法
掉鱼的猫1 小时前
跳出 Fatjar 的束缚:Solon 插件的体外扩展(E-Spi)与热插拔(H-Spi)
java
workflower2 小时前
案例:大模型驱动的“发现- 研判- 整改- 验证”全闭环治理体系
人工智能·深度学习·机器学习·设计模式·机器人
Bill FANG2 小时前
从原生Java NIO到Netty重构:充电桩Socket服务端高性能改造实战
java·重构·nio
2601_955759412 小时前
Claude API 成本审计:该看哪些指标,怎么分析更靠谱
java
带刺的坐椅2 小时前
跳出 Fatjar 的束缚:Solon 插件的体外扩展(E-Spi)与热插拔(H-Spi)
java·jar·solon·plugin·fatjar