Java 23 種設計模式:從踩坑到精通 | 番外:外觀模式 —— 物流訂單處理實戰(zhàn)
Java 23 種設計模式從踩坑到精通 | 番外外觀模式 —— 物流訂單處理實戰(zhàn)摘要外觀模式為子系統(tǒng)中的一組接口提供一個統(tǒng)一的高層接口讓客戶端只需一鍵操作即可完成原本需要多次調(diào)用的復雜流程。本文結(jié)合**智能物流中“訂單處理系統(tǒng)”**的場景完整展示如何用外觀模式封裝訂單校驗、庫存扣減、支付處理、配送調(diào)度、消息通知等五個子系統(tǒng)的協(xié)作讓你徹底掌握“化繁為簡”的設計精髓。?本文閱讀地圖3 分鐘速覽為什么下單流程不能直接暴露給客戶端? 外觀模式核心角色外觀類與子系統(tǒng)手寫物流訂單門面一行代碼完成下單、取消 外觀 vs 適配器簡化 vs 轉(zhuǎn)換 面試必問“外觀模式和適配器模式有什么區(qū)別”《Java 23 種設計模式從踩坑到精通》開篇系列介紹與目錄 正篇外觀模式 Facade —— 給復雜系統(tǒng)裝一個“一鍵啟動” 當前番外 · 外觀模式 × 物流訂單處理 返回系列總目錄1. 物流訂單處理的復雜流程在智能物流系統(tǒng)中一個簡單的下單操作背后涉及訂單校驗、庫存檢查、支付處理、運費計算、攬收調(diào)度、短信通知等多個子系統(tǒng)。如果讓客戶端直接調(diào)用這些子系統(tǒng)代碼會變得臃腫且耦合嚴重// 客戶端直接調(diào)用子系統(tǒng)步驟多、易遺漏、難維護OrderServiceorderServicenewOrderService();PaymentServicepaymentServicenewPaymentService();InventoryServiceinventoryServicenewInventoryService();ShippingServiceshippingServicenewShippingService();NotificationServicenotificationServicenewNotificationService();if(orderService.validateOrder(info)){if(inventoryService.checkStock(sku,quantity)){OrderorderorderService.createOrder(info);doublefeeshippingService.calculateShippingFee(address,weight);PaymentResultpaypaymentService.processPayment(order,fee);if(pay.isSuccess()){inventoryService.deductStock(sku,quantity);shippingService.schedulePickup(order);notificationService.sendShipmentNotice(order,user);}}}外觀模式的解決思路提供一個統(tǒng)一的LogisticsOrderFacade外觀類把上述復雜流程封裝在placeOrder()方法中??蛻舳酥恍枵{(diào)用一次外觀方法無需關(guān)心內(nèi)部有多少子系統(tǒng)、調(diào)用順序如何、出錯如何處理。1.1 你的場景該不該用外觀判斷標準是 → 用外觀否 → 用其他方式需要為多個子系統(tǒng)提供統(tǒng)一入口??子系統(tǒng)復雜調(diào)用步驟多??希望降低客戶端與子系統(tǒng)的耦合??子系統(tǒng)簡單只有一兩個類?直接調(diào)用即可2. 外觀模式 UML物流訂單處理場景3. 完整源碼實現(xiàn)3.1 子系統(tǒng)A訂單服務 (OrderService)importjava.util.UUID;publicclassOrderService{publicbooleanvalidateOrder(OrderInfoinfo){System.out.println( 訂單服務校驗訂單信息...);if(info.getSku()null||info.getSku().isEmpty()||info.getQuantity()0||info.getAddress()null){System.out.println( ? 訂單服務校驗失敗);returnfalse;}System.out.println( ? 訂單服務校驗通過);returntrue;}publicOrdercreateOrder(OrderInfoinfo){OrderordernewOrder(UUID.randomUUID().toString(),info);order.setStatus(OrderStatus.CREATED);System.out.printf( ? 訂單服務訂單創(chuàng)建成功 | 訂單號%s\n,order.getOrderId());returnorder;}publicvoidupdateOrderStatus(StringorderId,OrderStatusstatus){System.out.printf( 訂單服務訂單[%s]狀態(tài)更新為 %s\n,orderId,status);}}// 支撐類classOrder{privateStringorderId;privateOrderInfoinfo;privateOrderStatusstatus;// 構(gòu)造器與 getter/setter 省略...}classOrderInfo{privateStringsku;privateintquantity;privateStringaddress;privatedoubleweight;// 構(gòu)造器與 getter 省略...}enumOrderStatus{CREATED,PAID,SHIPPED,COMPLETED,CANCELLED,FAILED}白話訂單服務只關(guān)心訂單的驗證與狀態(tài)變更不涉及支付或物流。3.2 子系統(tǒng)B支付服務 (PaymentService)publicclassPaymentService{publicPaymentResultprocessPayment(Orderorder,doubleamount){System.out.printf( 支付服務處理支付 | 訂單[%s] | 金額¥%.2f\n,order.getOrderId(),amount);System.out.printf( ? 支付服務支付成功\n);returnnewPaymentResult(true,PAYSystem.currentTimeMillis());}publicbooleanrefund(StringorderId,doubleamount){System.out.printf( 支付服務退款成功 | 訂單[%s]\n,orderId);returntrue;}}classPaymentResult{privatebooleansuccess;privateStringpaymentId;// 構(gòu)造器...}3.3 子系統(tǒng)C庫存服務 (InventoryService)importjava.util.Map;importjava.util.concurrent.ConcurrentHashMap;publicclassInventoryService{privatefinalMapString,IntegerstockMapnewConcurrentHashMap();publicInventoryService(){stockMap.put(SKU001,100);stockMap.put(SKU002,50);stockMap.put(SKU003,200);}publicbooleancheckStock(Stringsku,intquantity){intcurrentstockMap.getOrDefault(sku,0);booleanokcurrentquantity;System.out.printf( 庫存服務檢查庫存 | SKU[%s] | %s\n,sku,ok?充足:不足);returnok;}publicvoiddeductStock(Stringsku,intquantity){stockMap.computeIfPresent(sku,(k,v)-v-quantity);System.out.printf( ? 庫存服務扣減成功 | SKU[%s] -%d\n,sku,quantity);}publicvoidrestoreStock(Stringsku,intquantity){stockMap.computeIfPresent(sku,(k,v)-vquantity);System.out.printf( ? 庫存服務恢復庫存 | SKU[%s] %d\n,sku,quantity);}}3.4 子系統(tǒng)D配送服務 (ShippingService)publicclassShippingService{publicdoublecalculateShippingFee(Stringaddress,doubleweight){doublefee10.0Math.max(0,weight-1)*5;System.out.printf( 配送服務運費 | 地址%s | 費用¥%.2f\n,address,fee);returnfee;}publicShipmentschedulePickup(Orderorder){StringtrackingNoTRKSystem.currentTimeMillis();System.out.printf( ? 配送服務已安排攬收 | 運單號%s\n,trackingNo);returnnewShipment(trackingNo,order.getOrderId());}}classShipment{/* trackingNo, orderId */}enumShipmentStatus{PENDING,PICKED_UP,IN_TRANSIT,DELIVERED}3.5 子系統(tǒng)E通知服務 (NotificationService)publicclassNotificationService{publicvoidsendOrderConfirmation(Orderorder,Stringuser){System.out.printf( 通知訂單確認 → 用戶[%s]\n,user);}publicvoidsendPaymentSuccess(Orderorder,Stringuser){System.out.printf( 通知支付成功 → 用戶[%s]\n,user);}publicvoidsendShipmentNotice(Orderorder,Stringuser){System.out.printf( 通知已發(fā)貨 → 用戶[%s]\n,user);}publicvoidsendOrderCancelled(Orderorder,Stringuser){System.out.printf( 通知訂單取消 → 用戶[%s]\n,user);}}3.6 外觀類物流訂單門面 (LogisticsOrderFacade)publicclassLogisticsOrderFacade{privatefinalOrderServiceorderServicenewOrderService();privatefinalPaymentServicepaymentServicenewPaymentService();privatefinalInventoryServiceinventoryServicenewInventoryService();privatefinalShippingServiceshippingServicenewShippingService();privatefinalNotificationServicenotificationServicenewNotificationService();publicOrderResultplaceOrder(OrderInfoorderInfo,Stringuser){System.out.println(\n 開始處理下單...);// 1. 校驗 庫存if(!orderService.validateOrder(orderInfo))returnOrderResult.failure(校驗失敗);if(!inventoryService.checkStock(orderInfo.getSku(),orderInfo.getQuantity()))returnOrderResult.failure(庫存不足);// 2. 創(chuàng)建訂單 通知OrderorderorderService.createOrder(orderInfo);notificationService.sendOrderConfirmation(order,user);// 3. 運費 支付doubleshippingFeeshippingService.calculateShippingFee(orderInfo.getAddress(),orderInfo.getWeight());doubletotal99.99*orderInfo.getQuantity()shippingFee;PaymentResultpaypaymentService.processPayment(order,total);if(!pay.isSuccess()){orderService.updateOrderStatus(order.getOrderId(),OrderStatus.FAILED);returnOrderResult.failure(支付失敗);}orderService.updateOrderStatus(order.getOrderId(),OrderStatus.PAID);notificationService.sendPaymentSuccess(order,user);// 4. 扣減庫存 配送inventoryService.deductStock(orderInfo.getSku(),orderInfo.getQuantity());ShipmentshipmentshippingService.schedulePickup(order);notificationService.sendShipmentNotice(order,user);orderService.updateOrderStatus(order.getOrderId(),OrderStatus.SHIPPED);System.out.println(? 下單完成);returnOrderResult.success(order.getOrderId(),pay.getPaymentId(),shipment.getTrackingNo());}publicbooleancancelOrder(StringorderId,Stringuser){System.out.println(\n 取消訂單...);paymentService.refund(orderId,99.99);orderService.updateOrderStatus(orderId,OrderStatus.CANCELLED);notificationService.sendOrderCancelled(newOrder(orderId,null),user);System.out.println(? 取消完成);returntrue;}}classOrderResult{/* success, orderId, paymentId, trackingNo, errorMsg */}白話外觀類的placeOrder就像前臺接待客戶說“我要下單”它就會按固定流程走完所有環(huán)節(jié)客戶完全不需知道背后有多少個部門在協(xié)作。3.7 客戶端測試publicclassClient{publicstaticvoidmain(String[]args){LogisticsOrderFacadefacadenewLogisticsOrderFacade();// 正常下單OrderResultr1facade.placeOrder(newOrderInfo(SKU001,2,北京市朝陽區(qū),3.5),張三);if(r1.isSuccess()){System.out.printf(訂單號%s, 運單號%s\n,r1.getOrderId(),r1.getTrackingNo());}// 庫存不足OrderResultr2facade.placeOrder(newOrderInfo(SKU999,1000,上海市,1.0),李四);if(!r2.isSuccess())System.out.println(失敗原因r2.getErrorMsg());// 取消訂單facade.cancelOrder(r1.getOrderId(),張三);}}4. 運行結(jié)果 開始處理下單... 訂單服務校驗訂單信息... ? 庫存服務檢查庫存 | SKU[SKU001] | 充足 ? 訂單服務訂單創(chuàng)建成功 通知訂單確認 → 用戶[張三] 配送服務運費 | 費用¥22.50 支付服務支付成功 訂單服務狀態(tài)更新為 PAID 通知支付成功 → 用戶[張三] ? 庫存服務扣減成功 ? 配送服務已安排攬收 | 運單號TRK... 通知已發(fā)貨 → 用戶[張三] 訂單服務狀態(tài)更新為 SHIPPED ? 下單完成 訂單號..., 運單號TRK... 開始處理下單... 庫存服務檢查庫存 | SKU[SKU999] | 不足 失敗原因庫存不足 取消訂單... 支付服務退款成功 訂單服務狀態(tài)更新為 CANCELLED 通知訂單取消 → 用戶[張三] ? 取消完成5. 核心角色回顧角色職責對應代碼Facade統(tǒng)一入口封裝流程LogisticsOrderFacadeSubsystem獨立處理各自業(yè)務邏輯OrderService,PaymentService,InventoryService,ShippingService,NotificationService6. 外觀模式 vs 適配器模式對比項外觀模式適配器模式意圖簡化接口隱藏復雜性轉(zhuǎn)換接口讓不兼容的類協(xié)同工作關(guān)注點降低客戶端調(diào)用難度解決接口不兼容問題子系統(tǒng)感知子系統(tǒng)不知道外觀的存在適配器持有被適配者被適配者不知道適配器典型應用物流訂單門面、JdbcTemplateInputStreamReader、對接第三方快遞API一句話記憶外觀是“一鍵啟動”——把復雜流程變成一個方法適配器是“轉(zhuǎn)接頭”——把不兼容的接口轉(zhuǎn)成你想要的格式。7. 外觀模式的優(yōu)缺點優(yōu)點缺點簡化客戶端調(diào)用降低耦合可能成為“上帝類”所有請求都經(jīng)過外觀保護子系統(tǒng)客戶端不會誤用危險方法新增子系統(tǒng)可能需要修改外觀類分層清晰可作為層間解耦手段高級用戶可能被隱藏了有用的子系統(tǒng)細節(jié)8. 六大設計原則體現(xiàn)原則體現(xiàn)單一職責外觀類只負責流程編排不實現(xiàn)具體業(yè)務開閉原則新增子系統(tǒng)可能需要修改外觀但可結(jié)合工廠緩解里氏替換子系統(tǒng)可替換升級不影響外觀依賴倒置客戶端依賴外觀抽象接口可進一步解耦接口隔離外觀提供精簡的高層接口避免“胖接口”迪米特法則客戶端只與外觀交互符合最少知識原則附 外觀模式 UML源碼物流訂單處理場景startuml title Java 23 種設計模式從踩坑到精通 footer 折哥 | 智能物流與Java實戰(zhàn) 1. 全局樣式配置 skinparam backgroundColor #FEFEFE skinparam shadowing false skinparam defaultFontName Microsoft YaHei skinparam classBorderColor #333333 skinparam classFontColor #1A1A1A skinparam classFontSize 14 skinparam noteFontSize 12 skinparam noteFontColor #555555 skinparam arrowColor #555555 skinparam classBackgroundColor #F9F9F9 2. 外觀類 - 物流訂單門面 class LogisticsOrderFacade { - orderService : OrderService - paymentService : PaymentService - inventoryService : InventoryService - shippingService : ShippingService - notificationService : NotificationService placeOrder(orderInfo) : OrderResult cancelOrder(orderId) : boolean } note right of LogisticsOrderFacade b外觀類物流訂單門面/b -- 為客戶端提供統(tǒng)一的下單入口 封裝內(nèi)部多個子系統(tǒng)的復雜調(diào)用流程 客戶端無需了解內(nèi)部細節(jié) end note 3. 子系統(tǒng)類 class OrderService { validateOrder(info) : boolean createOrder(info) : Order updateOrderStatus(id, status) } note right of OrderService b子系統(tǒng)A訂單服務/b -- 負責訂單校驗、創(chuàng)建、狀態(tài)更新 end note class PaymentService { processPayment(order, amount) : PaymentResult refund(orderId, amount) : boolean } note right of PaymentService b子系統(tǒng)B支付服務/b -- 負責支付處理、退款 end note class InventoryService { checkStock(sku, quantity) : boolean deductStock(sku, quantity) restoreStock(sku, quantity) } note right of InventoryService b子系統(tǒng)C庫存服務/b -- 負責庫存檢查、扣減、恢復 end note class ShippingService { calculateShippingFee(address, weight) : double schedulePickup(order) : Shipment trackShipment(trackingNo) : ShipmentStatus } note right of ShippingService b子系統(tǒng)D配送服務/b -- 負責運費計算、攬收調(diào)度、物流跟蹤 end note class NotificationService { sendOrderConfirmation(order, user) sendPaymentSuccess(order, user) sendShipmentNotice(order, user) sendOrderCancelled(order, user) } note bottom of NotificationService b子系統(tǒng)E通知服務/b -- 負責短信、郵件、站內(nèi)信通知 end note 4. 關(guān)系連線 LogisticsOrderFacade -- OrderService : 委托 LogisticsOrderFacade -- PaymentService : 委托 LogisticsOrderFacade -- InventoryService : 委托 LogisticsOrderFacade -- ShippingService : 委托 LogisticsOrderFacade -- NotificationService : 委托 enduml 《Java 23 種設計模式從踩坑到精通》快速導航開篇系列介紹與目錄正篇外觀模式 Facade —— 給復雜系統(tǒng)裝一個“一鍵啟動”當前番外 · 外觀模式 × 物流訂單處理你在這里創(chuàng)建型模式匯總結(jié)構(gòu)型模式匯總行為型模式匯總 關(guān)注《Java 23 種設計模式從踩坑到精通》用 25 篇文章徹底吃透設計模式。福利預告全系列代碼及 UML 源碼將在完結(jié)時統(tǒng)一打包開放點擊「關(guān)注」「收藏」第一時間獲取。 除了設計模式我也在深挖智能物流實戰(zhàn)WMS、托盤調(diào)度、機器學習落地。歡迎點擊頭像看看專欄 《出版社物流WMS智能調(diào)度實戰(zhàn)》、《電商多平臺電子面單對接實戰(zhàn)》。技術(shù)相通思路可鑒。

相關(guān)新聞

Unsloth 是一款專注于大語言模型高效運行與訓練的開源框架,核心目標是降低LLM微調(diào)門檻,讓普通用戶也能在消費級硬件上完成模型訓練任務。

Unsloth 是一款專注于大語言模型高效運行與訓練的開源框架,核心目標是降低LLM微調(diào)門檻,讓普通用戶也能在消費級硬件上完成模型訓練任務。

Unsloth 是一款專注于大語言模型高效運行與訓練的開源框架,核心目標是降低LLM微調(diào)門檻,讓普通用戶也能在消費級硬件上完成模型訓練任務。 官網(wǎng):Unsloth - Train and Run Models Locally repo:https://github.com/unslothai/unsl…

2026/7/30 0:21:09 閱讀更多
[GESP202606 四級] 掃雷

[GESP202606 四級] 掃雷

B4557 [GESP202606 四級] 掃雷 https://www.luogu.com.cn/problem/B4557 中國計算機學會(CCF)2026年6月C四級講解——掃雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四級] 掃雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:01:06 閱讀更多