设计模式之门面模式详解

设计模式之门面模式详解设计模式之门面模式详解文章目录设计模式之门面模式详解一 什么是门面模式二 门面模式的应用场景三 门面模式的角色组成四 门面模式示例一 什么是门面模式门面模式 FacadePatter 又叫外观

大家好,欢迎来到IT知识分享网。

设计模式之门面模式详解

一、什么是门面模式

门面模式(Facade Pattern) 又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口 。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型模式。在我们日常编码中也在无意中大量的使用着门面模式,例如ServiceA中调用其他多个Service的方法,然后再将ServiceA的方法暴露给Controller调用,ServiceA就相当于一个门面使得Controller能够间接的调用其他Service子系统,这也就是门面模式的一种应用。

二、门面模式的应用场景

  • 子系统越来越复杂,增加门面模式提供简单接口
  • 构建多层系统结构,利用门面对象作为每层的入口,简化层间调用

三、门面模式的角色组成

  • 外观角色(Facade): 也称门面角色,系统对外的统一接口;
  • 子系统角色(SubSystem): 可以同时有一个或多个SubSystem。每个SubSystem都不是一个单独的类,而是一个类的集合。SubSystem并不知道Facade 的存在,对于SubSystem而言,Facade只是另外一个客户端而已(即Facade对SubSystem是透明的)。

四、门面模式通用写法

我们先分别创建3个子系统的业务逻辑SubSystemASubSystemBSubSystemC

/ * 子系统角色 - 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(); } } 

五、门面模式在业务中的应用

需求:现有积分、支付、库存、物流系统,需要做一个积分兑换商城

  1. 创建商品类
 / * 商品详情信息 * * @author zdp * @date 2022/9/3 14:52 */ @Data @Builder public class GoodsInfo { 
    private String name; private Integer integral; private BigDecimal price; } 
  1. 积分系统
 / * 积分系统 * * @author zdp * @date 2022/9/3 14:51 */ @Slf4j public 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; } } 
  1. 库存系统
/ * 库存系统 * * @author zdp * @date 2022/9/3 14:54 */ @Slf4j public 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; } } 
  1. 支付系统
/ * 支付系统 * * @author zdp * @date 2022/9/3 14:52 */ @Slf4j public 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; } } 
  1. 物流系统
/ * 物流系统 * * @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()); } } 
  1. 外观角色门面
/ * 外观角色 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; } } 
  1. 测试
 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); } } } 

在这里插入图片描述

六、门面模式优缺点

  • 优点
    • 简化了调用过程,无需深入了解子系统,以防给子系统带来风险
    • 减少系统依赖,松散耦合
    • 更好地划分访问层次,提高了安全性
    • 遵循迪米特法则,即最少知道原则
  • 缺点
    • 当增加子系统和扩展子系统行为时,可能容易带来风险
    • 不符合开闭原则
    • 某些情况下可能违背单一职责原则

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/116474.html

(0)
上一篇 2025-11-28 18:10
下一篇 2025-11-28 18:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信