10-A-外观模式详解
10-A-外观模式详解关键词外观模式、门面、下单流程、SDK 封装、上帝类外观模式解决一个问题给复杂子系统提供一个简单的统一入口。调用方不需要知道下单背后有校验、锁库存、算价、建单、发事件五个子系统——它只调一个placeOrder()。外观是最直觉的模式也是最容易做坏的模式做成上帝类。 术语速查表术语人话解释外观Facade子系统的统一入口类把多步调用收成一个方法子系统Subsystem被封装的各个模块库存/价格/订单/事件上帝类反模式外观把所有逻辑都自己写了而不是委托门面 编排好的外观只做编排决定调用顺序和事务边界不做实现一、不用外观的问题Controller 直接调五个服务完成下单// ❌ Controller 里编排全部细节PostMapping(/order)publicResultplace(RequestBodyPlaceOrderRequestreq){// (1) 校验riskService.check(req.getUserId(),req.getSkuList());limitService.checkPurchaseLimit(req.getUserId(),req.getSkuList());// (2) 算价PriceResultpricepriceService.calculate(req.getSkuList(),req.getCouponId());// (3) 锁库存for(SkuItemitem:req.getSkuList()){inventoryService.lock(item.getSkuId(),item.getCount());}// (4) 建单OrderorderorderService.create(req.getUserId(),req.getSkuList(),price);// (5) 发事件eventPublisher.publish(newOrderCreatedEvent(order.getOrderNo()));returnResult.ok(order.getOrderNo());}痛点编排逻辑泄漏到 Controller——App、小程序、开放平台三个入口就要复制三遍步骤顺序有讲究先算价还是先锁库存散落在调用方容易写错事务边界、失败补偿没人统一管单元测试要 mock 五个服务。二、模式结构App 端小程序端开放平台OrderFacade.placeOrderRiskService风控校验PriceService算价InventoryService锁库存OrderService建单EventPublisher发事件外观只做编排决定顺序、管事务、处理失败——具体逻辑仍在各子系统里。三、业务场景下单门面ServicepublicclassOrderFacade{privatefinalRiskServiceriskService;privatefinalLimitServicelimitService;privatefinalPriceServicepriceService;privatefinalInventoryServiceinventoryService;privatefinalOrderServiceorderService;privatefinalApplicationEventPublishereventPublisher;publicOrderFacade(RiskServiceriskService,LimitServicelimitService,PriceServicepriceService,InventoryServiceinventoryService,OrderServiceorderService,ApplicationEventPublishereventPublisher){this.riskServiceriskService;this.limitServicelimitService;this.priceServicepriceService;this.inventoryServiceinventoryService;this.orderServiceorderService;this.eventPublishereventPublisher;}/** * 下单统一入口所有端都调这一个方法。 * 编排顺序是业务决策先校验(便宜) → 再算价 → 再锁库存(贵) → 建单 → 发事件 */Transactional(rollbackForException.class)publicOrderResultplaceOrder(PlaceOrderCommandcmd){// (1) 校验风控 限购失败快放最前riskService.check(cmd.getUserId(),cmd.getItems());limitService.checkPurchaseLimit(cmd.getUserId(),cmd.getItems());// (2) 算价优惠券、活动、运费PriceResultpricepriceService.calculate(cmd.getItems(),cmd.getCouponId());// (3) 锁库存最贵的操作放校验之后减少无效锁定ListLonglockednewArrayList();try{for(SkuItemitem:cmd.getItems()){inventoryService.lock(item.getSkuId(),item.getCount());locked.add(item.getSkuId());}// (4) 建单OrderorderorderService.create(cmd.getUserId(),cmd.getItems(),price);// (5) 发事件事务提交后再发用 AFTER_COMMIT 监听器见 19-A 观察者篇eventPublisher.publishEvent(newOrderCreatedEvent(order.getOrderNo()));returnOrderResult.success(order.getOrderNo());}catch(Exceptione){// 失败补偿已锁的库存要释放外观统一管理补偿调用方无感locked.forEach(skuId-inventoryService.unlock(skuId,cmd.getCount(skuId)));throwe;}}}Controller 瘦身成一行RestControllerpublicclassOrderController{privatefinalOrderFacadeorderFacade;PostMapping(/order)publicResultStringplace(RequestBodyValidPlaceOrderRequestreq){returnResult.ok(orderFacade.placeOrder(req.toCommand()).getOrderNo());}}外观带来的收益三个端复用同一套编排顺序/事务/补偿只写一遍步骤顺序这个业务决策有了唯一权威出处测试外观时 mock 子系统即可验证编排逻辑子系统内部重构如算价拆成促销运费两步不影响调用方。四、外观的三种常见形态形态例子说明服务编排门面OrderFacade收口多子系统调用顺序 事务 补偿SDK 门面支付 SDK 的PayClient.pay()把签名/加密/HTTP/重试/证书全藏起来框架门面SLF4JLoggerFactory、SpringJdbcTemplate对复杂 API 的极简包装SLF4J 是门面模式Facade 的另一种译法的命名来源应用只依赖slf4j-api底层日志实现随便换。五、框架中的同款实现框架应用说明SLF4JLogger/LoggerFactory日志门面名字就叫 FacadeSpringJdbcTemplate把 Connection/Statement/ResultSet/异常翻译收成一个 executeSpringTransactionTemplate编程式事务的门面JDKjavax.faces.context.FacesContext、URL.openStream()隐藏底层协议细节MyBatisSqlSessionselectOne/insert 门面背后是 Executor/StatementHandler 一族六、外观 vs 中介者 vs 适配器模式方向意图外观单向调用方 → 子系统简化入口子系统不知道外观存在中介者双向同事对象互相通信都经过它收敛网状交互见 17-A适配器转换接口不兼容的调和见 06-A一句话外观是我替你把复杂的都做了中介者是你们别互相打电话了都打给我。七、常见误用与生产事故误用一外观变上帝类// ❌ 外观里写了 800 行算价细节、300 行库存细节——不是编排是搬家publicclassOrderFacade{publicOrderResultplaceOrder(...){// 算价的 11 种优惠叠加逻辑全写在这里...}}判断标准外观方法的每一行应该是调用某个子系统 处理其结果一旦出现成块的业务算法就该下沉到子系统。外观的代码行数应该远小于它编排的子系统总和。误用二绕过外观直接调子系统团队定了OrderFacade统一入口但某个新需求图快直接调inventoryService.lock()跳过了风控校验——刷单团伙发现这个接口没有风控一夜锁光爆款库存。防御子系统方法收窄可见性package-private或加注解标记InternalUseOnlyArchUnit 规则Controller 不允许直接依赖 InventoryService必须经过 Facade关键校验风控/限购下沉到子系统自身做兜底——门面是便利不是唯一防线。事故门面方法上事务嵌套 RPC 导致长事务placeOrder加了Transactional其中锁库存是跨服务 RPC3s 超时。大促时库存服务抖动DB 连接被事务占住 3 秒不释放连接池耗尽整个订单库不可用。修复事务边界收缩只包住本地 DB 操作建单RPC 移出事务跨服务一致性用本地消息表 补偿替代大事务外观编排的纪律事务里不做 RPCRPC 失败靠补偿——这条写进 CR 检查单。八、总结外观的核心给复杂子系统一个简单统一的入口多端复用、编排收口。好外观只做编排顺序、事务、补偿是它的职责业务算法必须留在子系统里否则就是上帝类。门面不是唯一防线关键校验在子系统内兜底 ArchUnit 强制走门面。事务纪律门面方法的事务里不做 RPC——长事务是门面最常见的生产事故。代价外观可能变成什么都往里塞的垃圾场需要 CR 守住只编排不实现的边界。上一篇09-A-装饰器模式详解下一篇11-A-享元模式详解

相关新闻

gocv图像处理:水平投影与垂直投影实现文本行切分

gocv图像处理:水平投影与垂直投影实现文本行切分

做图像处理做得久了,难免有个体会:不少看着高级的活儿,根基反而是特别朴素的小操作。比如把一张合同扫描件里的文字块自动拆成一行一行、再拆成一个一个字符,很多人上来就考虑上模型,可实际上真正第一步往往是先把图做…

2026/10/18 6:47:54 阅读更多 →
智能问数核心实践:多策略召回与精排的工程方案

智能问数核心实践:多策略召回与精排的工程方案

1. 智能问数为什么难:核心不是"写SQL",而是"找对表和找对列"1.1 从传统BI到自然语言问数的需求变化做自然语言问数这几年,我最大的体感是:大家一开始都以为难点在"让大模型写SQL",真正上…

2026/10/18 6:46:54 阅读更多 →
PHP代码审计实战:六类致命反模式与漏洞挖掘指南

PHP代码审计实战:六类致命反模式与漏洞挖掘指南

前阵子给一套老系统做例行排查,翻到一个导出模块的时候,我看到了那行再熟悉不过的代码:一段从GET参数拿来的字符串,被直接拼进了一条SQL查询,然后mysqli_query一把梭。看到它的瞬间,我的脑子里冒出了两句话…

2026/10/18 6:46:54 阅读更多 →

最新新闻

增量索引实战:新文档怎么做到分钟级可检索

增量索引实战:新文档怎么做到分钟级可检索

个人主页&#xff1a;> for_ever_love__ <&#xff08;欢迎各位大佬莅临&#x1f60a;&#xff09; 其他栏目: > 大模型开发从0到1 < 其他栏目: > iOS项目总结大全 < 其他栏目: > 我想学python了 < 其他栏目: > iOS UI < 文章目录增量索引实战&a…

2026/10/18 21:45:10 阅读更多 →
Python多模态情感分析实战:CCA对齐+门控融合工程实现

Python多模态情感分析实战:CCA对齐+门控融合工程实现

简介&#xff1a;本资源是一套完整的多模态融合情感分析实战项目&#xff0c;面向计算机专业本科生及人工智能初学者&#xff0c;聚焦文本、语音、图像、视频四模态数据的情感联合建模与分析&#xff0c;适用于毕业设计、期末大作业及课程设计等高要求实践场景。压缩包共20个文…

2026/10/18 21:45:10 阅读更多 →
Onyx开源企业搜索深度解析:RAG与知识管理实践

Onyx开源企业搜索深度解析:RAG与知识管理实践

1. 为什么需要 Onyx&#xff1a;企业知识检索的三个死结1.1 知识分散&#xff1a;搜索引擎覆盖不到的角落先说我见过最多的场景。一个几十人的团队&#xff0c;文档其实不少&#xff1a;Wiki 里躺着架构设计、聊天工具里埋着半年前的决策、在线文档里散落着各种会议纪要和排期表…

2026/10/18 21:45:10 阅读更多 →
国产大模型对比:文心、豆包、通义...哪家最好?基于最公允大模型排行榜细致整理

国产大模型对比:文心、豆包、通义...哪家最好?基于最公允大模型排行榜细致整理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 21:45:10 阅读更多 →
协同过滤电影推荐系统毕设:Python实现核心算法与工程避坑全解析

协同过滤电影推荐系统毕设:Python实现核心算法与工程避坑全解析

简介&#xff1a;基于协同过滤推荐算法的电影推荐系统Python毕业设计项目&#xff0c;面向计算机相关专业毕业生、课程设计及期末大作业学生&#xff0c;也适合有Python基础、希望实战推荐系统开发的进阶学习者。整包共2000个文件&#xff0c;以py源码、html页面、css样式、js脚…

2026/10/18 21:45:10 阅读更多 →
大模型工具使用与函数调用:从原理到落地的完整指南

大模型工具使用与函数调用:从原理到落地的完整指南

1. 从"能聊天"到"能干活"&#xff1a;工具使用与函数调用到底在解决什么问题大模型刚火起来那阵子&#xff0c;大家最直观的体验就是"能聊"。你问它答&#xff0c;写诗写文案写代码&#xff0c;样样都行。但真把它扔进一个实际业务里&#xff0c…

2026/10/18 21:44:10 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →