门面设计模式

2023-11-06

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

1 什么是门面设计模式

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

增加一层

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

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

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

//订单系统
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
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
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
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 对象使用到外观模式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

门面设计模式 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • ROI Pooling层详解

    ROI Pooling层详解 原文链接 https blog deepsense ai region of interest pooling explained 目标检测typical architecture 通常可以分为两个阶段 1 r
  • NO.15 不得不说的以太坊跟ICO

    随着以太坊的出现 区块链进入了2 0时代 以太坊是个太神奇的东西 没有天才的想法 高超的技术以及黑客的精神是无法如此成功的 它实现了区块链项目的快速开发 快速实施 以太坊这个开发平台本身发行了一种币叫做以太币 ETH 使用此平台开发出来的应
  • APS系统介绍

    APS系统介绍 前言 听说新工作将是做APS系统 之前没接触过 所以查找了一些资料 整理学习记录于此 本文打算从以下几个方面来阐述 APS的概念 前提条件 怎么实现 优化算法 简单示例 APS概念 APS Advanced Planning
  • el-table表单实现点击编辑按钮对内容进行编辑

    el table表单实现点击编辑按钮对内容进行编辑 话不多说 先上效果图 这里我将按钮绑定了dialog对话框 避免直接在原有表行之间进行修改 因为后台管理系统多是响应式布局 使用dialog对话框可以更直观的让用户对内容进行编辑 而对于在
  • 【服务计算】docker实践报告

    docker实践报告 环境说明 准备docker环境 运行第一个容器 Docker基本操作 MySQL与容器化 拉取MySQL镜像 构建docker镜像 MySQL容器使用 Docker compose与多容器应用自动化部署 docker网
  • SpringBoot运行源码分析:Spring应用上下文刷新,java主流框架面试题

    protected void refresh ApplicationContext applicationContext Assert isInstanceOf AbstractApplicationContext class applic
  • 【eNSP】单臂路由+静态路由配置练习

    单臂路由 静态路由配置练习 单臂路由 又名子接口 实际上是一个逻辑接口 并不存在真正物理上的子接口 采用单臂路由 即在路由器上设置多个逻辑子接口 每个子接口都可以单独设置一个IP地址 对应于一个VLAN 由于物理路由接口只有一个 各子接口的
  • Flutter 实体类转String,String转实体类

    实体类转String方式 引用需要转换的包 import dart convert 转换方法 String jsonStr jsonEncode myInfosBeans String转实体类 引用转换包 import dart conve
  • render 怎么使用v-if

    在Vue中使用render函数 有些时候我们需要判断这个元素是否需要渲染 在正常的DOM结构中可以直接使用v if 但是 render函数中有些时候是无法使用v if 来进行判断 这时我们可以使用if 来判断是否添加该元素 render h
  • c++ 理解 关于构造函数和析构函数

    构造函数和析构函数 1 首先 C 有拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符和析构函数 构造函数可以先分为 默认构造函数和拷贝构造函数 如果我们在代码中不显示的自己声明构造函数的话 c 的编译器会为我们默认生成默认构造函数
  • STM32之ADC实验

    实验的基本功能 采集PC0引脚的输入电压 通过串口打印出采集的电压值 本实验是使用通道10 采集PC0引脚的输入电压 include stm32f10x h include stm32f10x usart h include
  • mac 卸载idea

    卸载MAC中的IDEA Intellij 首先在应用里面右键移动到垃圾桶 然后使用命令行 cd Users xxx Library 上面的xxx对应你的用户名 然后输入 rm rf Logs IntelliJIdeaxxx rm rf Pr
  • 域名续费怎么才能便宜?2023年腾讯云服务器和域名续费贵怎么续费便宜?

    背景 在腾讯云的有一个域名到期了需要续费 xyz续费居然有79元 真的贵 建议大家在购买域名之前参考我之前的文章 直接买个188元10年的top域名真的香 我是因为小程序都布置好了 如果重新更改域名太累了 所以只能续费 直接续费需要79元
  • 云服务器部署 Web 项目

    一 搭建 Java 部署环境 1 安装 JDK 2 安装 Tomcat 总结 3 安装 MySQL 1 依次安装 2 更改配置 3 启动 4 测试连接 二 部署 web 项目 1 给服务器准备好依赖的数据 2 微调我们的 Java 代码 3
  • Requests模块怎么设置字符编码

    Requests模块在发出网络请求时 支持设置字符编码 主要有以下两种方式 在请求头中设置字符编码 可以通过headers参数设置字符编码 例如 import requests url http www example com header
  • C# SuperSocket 手把手教你入门 傻瓜教程---11(FixedSizeReceiveFilter - 固定请求大小协议)不使用COMMAND

    SuperSocket内置的常用协议实现模版如下 1 TerminatorReceiveFilter SuperSocket SocketBase Protocol TerminatorReceiveFilter SuperSocket S
  • linux命令:修改用户密码

    修改用户密码用passwd命令 假设现在已经用root用户登陆 1 修改root用户密码 在终端直接输入 root armbian passwd New password 输入第一次密码 Retype new password 输入第二次密
  • 3个字节的空txt文本文件

    运行下面代码可以建立一个3个字节的空txt文本文件 想了解其原因的请参考文本文件的编码方式和unicode的具体资料 google上就有很多 System IO FileStream fs new System IO FileStream
  • matlab实现数值积分 【一】(trapz函数)

    目录 总述 函数调用格式 应用举例 例1 梯形法求积分 例2 不同步长对积分结果的影响 总述 数值积分问题是传统数值分析课程中的重要内容 如果被积函数的数学表达式未知 则需要由实测数据通过梯形算法求出积分的近似值 本文将介绍被积函数的数学表
  • 门面设计模式

    github GitHub QiuliangLee pattern 设计模式 1 什么是门面设计模式 门面设计模式是一种软件设计模式 也被称为外观 Facade 模式 它提供了一个简单的接口 让客户端能够访问复杂系统中的一组接口 通过门面模