设计模式之门面模式详解
设计模式之门面模式详解
文章目录
- 设计模式之门面模式详解
- 一、什么是门面模式
- 二、门面模式的应用场景
- 三、门面模式的角色组成
- 四、门面模式通用写法
- 五、门面模式在业务中的应用
- 六、门面模式优缺点
一、什么是门面模式
门面模式(Facade Pattern) 又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口 。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型模式。在我们日常编码中也在无意中大量的使用着门面模式,例如
ServiceA
中调用其他多个Service的方法,然后再将ServiceA
的方法暴露给Controller调用,ServiceA
就相当于一个门面使得Controller能够间接的调用其他Service子系统,这也就是门面模式的一种应用。
二、门面模式的应用场景
子系统越来越复杂,增加门面模式提供简单接口
构建多层系统结构,利用门面对象作为每层的入口,简化层间调用
三、门面模式的角色组成
门面模式的通用类图:
- 外观角色(Facade): 也称门面角色,系统对外的统一接口;
- 子系统角色(
SubSystem
): 可以同时有一个或多个SubSystem
。每个SubSystem
都不是一个单独的类,而是一个类的集合。SubSystem
并不知道Facade 的存在,对于SubSystem
而言,Facade只是另外一个客户端而已(即Facade对SubSystem
是透明的)。
四、门面模式通用写法
我们先分别创建3个子系统的业务逻辑SubSystemA
、SubSystemB
、SubSystemC
/*** 子系统角色 - SubSystemA** @author zdp* @date 2022/9/3 14:38*/
public class SubSystemA {public void doA() {System.out.println("doing A stuff");}}
/*** 子系统角色 - SubSystemB** @author zdp* @date 2022/9/3 14:38*/
public class SubSystemB {public void doB() {System.out.println("doing B stuff");}}
/*** 子系统角色 - SubSystemC** @author zdp* @date 2022/9/3 14:38*/
public class SubSystemC {public void doC() {System.out.println("doing C stuff");}}
紧接着再创建一个外观角色类Facade :
/*** 外观角色 Facade 相当于注入其他Service,封装其方法暴露给客户端** @author zdp* @date 2022/9/3 14:34*/
public class Facade {//相当于@Autowire注入private SubSystemA a = new SubSystemA();private SubSystemB b = new SubSystemB();private SubSystemC c = new SubSystemC();// 对外接口public void doA() {this.a.doA();}// 对外接口public void doB() {this.b.doB();}// 对外接口public void doC() {this.c.doC();}
}
编写测试类
/*** facade 通用写法** @author zdp* @date 2022/9/3 14:36*/
class Test {// 客户 (相当于Controller)public static void main(String[] args) {Facade facade = new Facade();facade.doA();facade.doB();facade.doC();}
}
五、门面模式在业务中的应用
需求:现有积分、支付、库存、物流系统,需要做一个积分兑换商城
- 创建商品类
/*** 商品详情信息** @author zdp* @date 2022/9/3 14:52*/@Data@Builderpublic class GoodsInfo {private String name;private Integer integral;private BigDecimal price;}
- 积分系统
/*** 积分系统** @author zdp* @date 2022/9/3 14:51*/@Slf4jpublic class IntegralSystem {/*** 扣减积分** @param info GoodsInfo* @author zdp* @date 2022/9/3 15:10* @return result*/public boolean deductIntegral(GoodsInfo info){log.info("商品【{}】扣减积分成功", info.getName());return true;}}
- 库存系统
/*** 库存系统** @author zdp* @date 2022/9/3 14:54*/@Slf4jpublic class StockSystem {public static int goodsStock = 2;/*** 扣减库存** @param info GoodsInfo* @author zdp* @date 2022/9/3 15:07* @return result*/public boolean deductStock(GoodsInfo info){goodsStock -= 1;if (goodsStock < 0) {log.info("商品【{}】扣减库存失败,库存不足~", info.getName());return false;}log.info("商品【{}】扣减库存成功~", info.getName());return true;}}
- 支付系统
/*** 支付系统** @author zdp* @date 2022/9/3 14:52*/@Slf4jpublic class PaymentSystem {StockSystem stock = new StockSystem();IntegralSystem integral = new IntegralSystem();/*** 付款** @param info GoodsInfo* @author zdp* @date 2022/9/3 15:08* @return result*/public boolean pay(GoodsInfo info){if (stock.deductStock(info)) {integral.deductIntegral(info);log.info("商品【{}】支付成功,准备发货~", info.getName());return true;}return false;}}
- 物流系统
/*** 物流系统** @author zdp* @date 2022/9/3 14:49*/
@Slf4j
public class LogisticsSystem {/*** 对接物流系统,商品发货** @param info goods info* @author zdp* @date 2022/9/3 14:57* @return java.lang.String 物流单号*/public void deliverGoods(GoodsInfo info){//对接物流系统...log.info("商品【{}】,进入物流系统,单号: {}", info.getName(), new Date().getTime());}
}
- 外观角色门面
/*** 外观角色 Facade 商品兑换门面 整合了支付和物流系统,使得前端开发逻辑处理简单,不用再调用多个系统** @author zdp* @date 2022/9/3 15:15*/public class GoodsFacadeSystem {PaymentSystem payment = new PaymentSystem();LogisticsSystem logistics = new LogisticsSystem();/*** 商品兑换** @param info GoodsInfo* @author zdp* @date 2022/9/3 15:16* @return 商品兑换结果*/public boolean exchange(GoodsInfo info){if (!payment.pay(info)) {return false;}logistics.deliverGoods(info);return true;}}
- 测试
public class Test {public static void main(String[] args) throws Exception{GoodsFacadeSystem facade = new GoodsFacadeSystem();for (int i = 0; i < 3; i++) {GoodsInfo info = GoodsInfo.builder().name("拖孩儿").integral(100).price(new BigDecimal("10.05")).build();facade.exchange(info);TimeUnit.MILLISECONDS.sleep(1);}}}
六、门面模式优缺点
- 优点
- 简化了调用过程,无需深入了解子系统,以防给子系统带来风险
- 减少系统依赖,松散耦合
- 更好地划分访问层次,提高了安全性
- 遵循迪米特法则,即最少知道原则
- 缺点
- 当增加子系统和扩展子系统行为时,可能容易带来风险
- 不符合开闭原则
- 某些情况下可能违背单一职责原则
设计模式之门面模式详解相关推荐
- 设计模式之模板方法模式详解
设计模式之模板方法模式详解 概述 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的 ...
- 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)
0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...
- 设计模式之桥接模式详解
设计模式之桥接模式详解 文章目录 设计模式之桥接模式详解 一.什么是桥接模式 二.桥接模式的应用场景 三.桥接模式的角色组成 四.桥接模式通用写法示例 五.桥接模式优缺点 一.什么是桥接模式 桥接模式 ...
- 设计模式之策略模式详解
设计模式之策略模式详解 概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车.可以坐汽车.可以坐火车.可以坐飞机. 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有 ...
- 设计模式之工厂模式详解(附应用举例实现)
文章目录 1 工厂模式介绍 2 工厂模式详解 2.1 简单工厂模式 2.1.1 简单工厂模式结构 2.1.2 简单工厂模式实现 2.1.3 简单工厂模式应用举例 2.2 工厂方法模式 2.2.1 工厂 ...
- 设计模式之桥接模式详解(附应用举例实现)
文章目录 1 桥接模式介绍 2 桥接模式详解 2.1 桥接模式结构 2.2 桥接模式实现 2.3 桥接模式应用实例 1 桥接模式介绍 毛笔和蜡笔是两种很常见的文具,它们都归属于画笔.假设我们需要大.中 ...
- 设计模式之原型模式详解(附应用举例实现)
文章目录 1 原型模式介绍 2 原型模式详解 2.1 原型模式结构 2.2 深克隆与浅克隆 2.2.1 浅克隆 2.2.2 深克隆 2.3 原型模式实现 2.3.1 通用实现方法 2.3.2 Java ...
- 设计模式之命令模式详解(附应用举例实现)
文章目录 1 命令模式介绍 2 命令模式详解 2.1 命令模式结构 2.2 命令模式实现 2.3 命令模式应用举例 3 实现命令队列 1 命令模式介绍 在现实生活中人们通过使用开关来控制一些电器的打开 ...
- 设计模式之组合模式详解(附应用举例实现)
文章目录 1 组合模式介绍 2 组合模式详解 2.1 组合模式结构 2.2 组合模式实现 2.3 组合模式应用举例 3 透明组合模式和安全组合模式 1 组合模式介绍 在我们的树形目录结构中,包含文件和 ...
最新文章
- php乱码解决方案,php中文乱码问题的4种解决方案
- JAVA学习笔记--初始化与清理
- 小米用户画像_鹅智库发布手机品牌用户画像 一二线城市最爱小米 5G领域或占先机...
- DOM-9 【实战】模块化开发Todolist(面向过程)
- 使用Mutex實現單一程式執行個體的注意事項(转)
- 调用toString()方法的注意事项
- 在Centos 6.5 X64下切割m3u8
- esxi 5.5运行linux拯救模式,启用Esxi 5.5 SSH 功能
- fork() 和 vfork()
- LeetCode58. 最后一个单词的长度
- 【Spring笔记】依赖注入
- 2021-09-15频繁项集的评估标准
- python继承方式是基于原型吗_【Python】python 普通继承方式和super继承方式
- 向量数量积公式_向量的数量积公式大全
- 数据处理——偏最小二乘法
- html黑洞效果,HTML5 Canvas炫酷宇宙黑洞引力特效
- 近观趣店,“审视”罗敏
- fastai 文本分类_使用Fastai v2和多标签文本分类器检查有毒评论
- c语言电脑重启代码,关于关机重启代码~!!!
- 一本通 1335:【例2-4】连通块