拆解零售商品架構的底層邏輯

来源:https://www.cnblogs.com/88223100/archive/2023/10/11/Decomposing-the-underlying-logic-of-retail-product-architecture.html
-Advertisement-
Play Games

一、引言 在當今數字化時代,零售業正迅速發展,消費者的購物行為和期望發生了巨大的變化。為了滿足不斷增長的需求,零售企業必須構建高度靈活、穩健可靠的商品系統。 本文將深入探討零售商品系統的底層邏輯,聚焦領域驅動設計(DDD)和複雜業務系統架構經驗,揭示其在零售業務中的應用和價值。 二、面臨的挑戰 商品 ...


一、引言

 

在當今數字化時代,零售業正迅速發展,消費者的購物行為和期望發生了巨大的變化。為了滿足不斷增長的需求,零售企業必須構建高度靈活、穩健可靠的商品系統。

 

本文將深入探討零售商品系統的底層邏輯,聚焦領域驅動設計(DDD)和複雜業務系統架構經驗,揭示其在零售業務中的應用和價值。

 

二、面臨的挑戰

 

商品系統幾乎貫穿了整個業務流程,比如:收銀機的掃碼加購、下單、商品詳情頁、小程式加購、營銷活動、進銷存、供應鏈、售後、履約等,各個業務環節都以商品為載體。由於商品系統的這種基礎性和核心性,它所面臨的挑戰也愈發顯得複雜而嚴峻。

 

挑戰一:廣泛行業需求的融合

 

零售領域擁有多元化的行業,每個行業對商品管理的需求都存在顯著差異。從超市便利店到酒店教培,再到生鮮行業,不同行業的商品屬性截然不同。

 

挑戰二:複雜業務鏈路的支撐

 

商品系統作為零售業務的中樞,需要支持從採購到銷售再到退貨的各個環節。這涉及到供應鏈、訂單、物流、結算、售後等多個業務域的協同運作。

 

挑戰三:面向B端與C端的雙重需求

 

商品系統不僅要為商家提供強大的商品管理工具,還需要為消費者提供良好的商品展示和購物體驗。B端需求關註商家的批量操作、庫存管理等,而C端需求則關註用戶的瀏覽、購買、支付等。如何在系統中同時滿足兩者的需求,保證系統的易用性和擴展性。

 

面對泛行業需求的融合、複雜業務鏈路的支撐以及B端與C端雙重需求,業務架構師需要有深刻的洞察力,結合架構的“道”與“術”,在複雜性中找到平衡,構建出穩定、靈活零售商品系統,為業務持續迭代提供有力支持。

 

三、架構“道”與“術”

 

架構不僅涉及技術層面的決策,還關乎對業務需求的深刻理解以及對系統演化的預判,它決定了系統的整體設計和演化方向。

 

1. 架構的“道”

 

架構的“道”強調系統的整體規劃、設計和演化策略。它包括以下核心要素:

 

  • 深刻的業務理解。在設計架構之前,要深刻理解業務需求,通過領域驅動設計(DDD)來捕捉業務的核心概念和領域模型,保證架構與業務的緊密契合。

  • 可演化與擴展性。架構需要具備演化的能力,以適應不斷變化的業務需求和技術進步。同時,它還應該有足夠的擴展性,以應對未來可能出現的挑戰和機會。

  • 業務驅動的設計。架構應該以業務為核心,將業務邏輯和技術方案相結合。通過領域建模,將業務的核心概念映射到系統架構中,實現領域模型的高度一致性。

 

2. 架構的“術”

 

架構的“術”關註具體的技術選型、設計和實現。它包括以下關鍵方面:

 

  • 分層與模塊化。將系統劃分為不同的層次和模塊,每個層次和模塊負責特定的功能。分層和模塊化有助於職責的清晰劃分,減少代碼的重覆性。

  • 設計原則與模式。技術設計時,需要考慮一系列設計原則和設計模式,如單一職責原則、開閉原則、依賴倒置等,構建松耦合、高擴展的系統。

  • 技術選型。選擇合適的技術棧是方案中的重要決策之一。技術棧涉及編程語言、中間件框架、資料庫等,它們直接影響到系統的性能、可擴展性和開發效率。

 

四、零售商品架構

 

1. “分治” 策略

 

零售商品關聯了非常多的業務模塊,比如:商品SPU、規格SKU、前臺類目、後臺類目、品牌、庫存、標品、屬性和模板等,不同業務模塊在橫向存在千絲萬縷的關係。同時隨著用戶規模擴大業務拓展,各個業務模塊垂直化建設也會加大,進一步加劇系統複雜度。

 

為瞭解決這一複雜性,我們首先採取“分而治之”,引入限界上下文,將大商品域進一步拆分為主商品、庫存、類目、屬性等一些列自治的領域,縮小業務域範圍,並按職責分為核心域、通用域、支撐域,每個領域專註於處理自己本域的特性問題,弱化橫向之間耦合,降低了複雜度。

 

圖片

 

領域內早期只有單一的普通商品,業務邏輯比較簡單。然而,隨著業務不斷迭代,商品涌現很多新玩法,如組合商品、臨時商品、虛擬商品、預售商品等,每一種商品類型都表現出獨特的規則和特性。

 

如果不同類型商品獨立構建,像一個個孤立的煙囪,勢必會導致重覆建設問題。一旦修改通用邏輯,不得不在多處進行重覆性改造,增加了維護成本。另一方面,將不同類型商品集中於一個主流程中,雖然可以減少重覆建設,但這也可能出現大量的 if、else邏輯以處理差異化邏輯,影響代碼整潔性。

 

為瞭解決這一問題,領域內我們採用 分解+編排的策略,結合主流設計模式,以構建高效、可維護的系統。

 

  • 分解:將複雜的業務邏輯分解為更小組件,使每個組件只關註一個特定功能。這種分解符合軟體設計的單一職責,同時降低單個組件的複雜度。

  • 編排:採用責任鏈選擇需要的業務組件進行串聯,通過組裝方式實現一個業務流程,保證了軟體的開閉原則,同時也實現同一個組件在不同的業務流程復用。

 

如何在領域內分解和編排?有什麼工具方法論可以開箱即用?

 

這裡推薦使用 “矩陣思維”,梳理每一個業務流程,自上而下分解將一個大流程拆解為若幹個小業務組件。以商品創建流程為例,橫向表示業務動作,縱向表示業務場景,中間表示詳細的業務流程。拆解後得到下麵表格所示的矩陣。

 

圖片

 

通過矩陣工具將橫、縱兩個維度的複雜度清晰展現出來,方便我們直觀發現不同流程之間的共性和特性,接下來就要考慮組件編排工作。

 

圖片

 

將標準化業務邏輯封裝成一個個獨立的業務組件,在應用層通過組件編排的方式組裝業務流程。每個業務動作都有自己獨享的編排流程,它輕量化易修改,承載業務功能的落地實現。

 

舉個例子,當我們接到業務方需求,開發一種新的組合商品,創建商品環節只需要增加兩個業務組件:檢查組合商品前置條件、記錄組合明細,然後復用其他組件快速編排出一個新介面。整個過程對其他業務沒有影響,符合軟體的開閉原則,並且大大降低測試工作量。

 

2. “抽象” 領域模型

 

新零售服務的行業非常多,不同行業的商品屬性差異非常大,下圖示例是商超便利店與教育培訓的商品。面對泛行業的“差異性”、“不確定性”特點,我們該如何架構系統?

 

如果每個行業單獨創建一套存儲結構,看似滿足了需求但成本巨大,而且靈活性也不高。

 

如果將所有行業的數據放在一個地方存儲,那差異化的數據結構如何滿足,而且很多欄位還涉及到校驗規則或作為搜索條件。不僅要能寫進去,還要讀出來。

 

圖片

 

軟體架構中解決複雜業務的另一法寶就是將業務需求抽象成領域模型,那什麼是領域模型,先來看下維基百科給出的定義

 

領域模型(Domain Model)記錄了一個系統中的關鍵概念和辭彙表,顯示出了系統中的主要實體之間的關係,並確定了它們的重要的方法和屬性。

 

領域模型是將現實世界的客觀對象抽象為一種信息結構,並能精確地反映業務領域的本質特征,這種信息結構不依賴於具體的編程語言,具有很強的獨立性。

 

這樣我們就可以將業務與技術實現分離,所有人的焦點放在領域模型,通過統一領域語言,讓業務專家、研發人員在一個頻道溝通,收集業務核心特征。下圖是零售商品的領域模型:

 

圖片

 

主商品模型的屬性根據其是否通用,拆分成兩部分,對於相對穩定的數據,如“商品名稱”、“類目”、“條形碼”、“商品類型”、“售賣單位”等放在主商品上。而對於“產地”、“上課時間”等不固定數據抽取到自定義屬性中,並與模板綁定,主商品只綁定一個模板標識號即可。

 

圖片


當商戶創建商品時,根據業務類型找到對應的模板和關聯的自定義屬性,自定義屬性主要包含以下內容:

 

  • component_config:主要是前端渲染頁面使用,如輸入框、下拉列表、單選、多選框等;

  • label:輸入框 左側的欄位標題說明;

  • rules:值校驗規則,用於校驗商戶輸入是否滿足要求。比如:“欄位是否必填”、“輸入文本長度”、“欄位是否只讀”、“欄位是否可見”、“正則校驗”等。

 

用戶填寫完商品頁面的各種輸入信息,並且通過所有校驗規則,接下會將發佈一條商品,核心欄位放在主商品,而對於“重量”、“起售份數”等非核心欄位與屬性“field_id”關聯,然後採用泛化集合存儲到模板實體。

 

細心的小伙伴可能發現,這裡的field_id是個重覆欄位如 保質期(expiration_data),每個商品都有這個欄位,如果商品表的數據量非常大,這種冗餘欄位會占用很大空間。針對這個問題,可以借鑒 Protocol Buffers 的設計思想,為每個屬性分配一個獨立編號,通過字典記錄它們的關聯關係。這樣模板實體中綁定的不再是英文欄位而是一個數字編號,空間會成倍的降低。

 

3.DDD 分層架構

 

一個好的系統一定有個好的架構模式,不管在六邊形架構還是Clean Architecture中,似乎更習慣把Domain作為最底層,而Infrastructure是作為上層來實現Domain的Repository,將業務複雜度和技術複雜度分離。

 

業務複雜度主要體現在領域模型,通過實體、屬性值、聚合根來呈現業務的本我,然後通過領域服務對實體數據驅動,完成一個生命周期。不管規則如何變化,最終通過模型來承接數據。

 

系統落地主要體現在代碼排兵佈陣,這裡就用到 DDD 分層架構。分層是為瞭解決技術複雜度,讓每一層有自己的專屬職責,如:數據轉換、RPC遠程調用、非同步消息解耦、緩存性能加速、動態配置中心、定時任務。

 

圖片

 

整個系統分為四層,每一層都有明確的職責定義:

 

1)介面層:定義介面服務,包括入參、響應結果,對外通過二方包的形式呈現。

 

2)應用層:表述應用和用戶的行為,對領域服務進行組合和編排,對領域實體中的欄位提取並轉換成外部想要的形式。如果寫服務,作為生產者對外發佈消息事件,當然也可以作為消費者,訂閱外部消息。這裡也是MQ消息和定時任務的觸發入口,所以也稱為觸發層。

 

3)領域層:用於表達業務概念和業務邏輯,是系統的核心。包含:實體、值對象、聚合根、領域服務、倉儲服務等。

 

  • 實體主要是承載業務的領域模型及關聯關係,以及自身的動作行為。有欄位變數,有方法,也成為充血模型。

  • 領域服務主要完成領域中跨實體或值對象的操作轉換而封裝的服務,領域服務對同一個實體的一個或多個方法進行封裝組合,對外隱藏領域層的業務邏輯實現,以黑盒形式對外服務。

  • 倉庫服務職責單一,主要負責將領域模型傳給存儲層,持久化存儲。考慮到存儲中間件的多樣化,為了避免多變性對領域層的干擾影響,這裡只定義介面,介面實現放在基礎設施層。通過依賴倒置保證了領域層的核心地位。

 

4)基礎設施層:為上層提供基礎技術能力。如MySQL資料庫操作、緩存數據讀和寫、遠程RPC介面防腐層封裝,以及其它中間件的初始化config 等,降低外部資源變化對系統的影響。

 

圖片

 

縱向,我們從技術視角分為四層,每層有自己的專屬職責。橫向,從業務維度切割為多個子域,如商品、庫存、類目等。落實到具體代碼,我們通過 package 實現代碼隔離。為了兼顧領域的內聚性,頂層包按領域劃分,每個分層內部再按模塊職責定義子包。

 

4.數據流轉

 

無論系統的複雜程度如何,其本質都歸結為數據操作。從本地存儲或遠程介面獲取數據,經過一些列的轉換、加工和組合等來表達業務邏輯。這一流程自上而下經歷多個階段,最終完成數據的持久化存儲,同時自下而上地通過各種轉換和加工,將數據最終展示給用戶。

 

圖片

 

為了有效限制各個分層數據模型的職責範圍,從而避免交織耦合,我們採取了數據模型分層的策略,將其分為三個主要類別:DO(資料庫持久對象)、VO(領域模型對象)和DTO(數據傳輸對象)。

 

資料庫持久對象為 DO,通過 Repository 介面完成 DO 到 VO 的領域模型轉換,然後通過領域服務向上暴露。

 

在這個架構中,資料庫持久對象(DO)承載了與資料庫之間的直接映射關係,通過Repository介面完成 DO 到 VO 的領域模型轉換,然後通過領域服務向上層暴露。在應用層,對領域模型 VO 進行一系列業務邏輯處理,最終轉換為 數據傳輸對象(DTO),以便與外部世界進行交互。DTO充當著外部和內部數據傳輸的媒介,它不僅可以承載所需數據,還能夠在傳輸過程中進行數據格式的轉換和優化,以適應不同的客戶端需求。

 

通過明確的分層和數據模型職責,我們能夠實現不同層次之間的解耦。這種解耦使得每個層次都可以專註於特定的任務,而不需要過多考慮其他層次的細節,保證系統低耦合特點,擴展性更強。

 

五、結語

 

在零售業的數字化浪潮下,構建高度靈活、穩健可靠的商品系統已成迫切需求。

 

面對業務挑戰,領域驅動設計與分解+編排策略成為解決問題的關鍵。架構的"道"註重業務理解與業務驅動設計,而"術"關註分層設計和模式運用。從抽象領域模型到DDD分層架構,系統持續演進。這些舉措以數據操作為核心,聚焦業務與技術,構建穩定、高效的零售商品系統,為業務發展保駕護航。

 

作者丨智慧經營開發部-宋志朋

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Decomposing-the-underlying-logic-of-retail-product-architecture.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 打包後的項目靜態資源無法使用,導致頁面空白 靜態資源無法使用,那就說明項目打包後,圖片和其他靜態資源文件相對路徑不對,此時找到config裡面的index.js,在build模塊下加入assetsPublicPath: './', 如下圖所示, 在History模式下配合使用nginx運行打包後的項 ...
  • # 浮動會帶來的影響 —— 會造成父標簽塌陷的問題 解決辦法: 方法一:自己加一個div,設置高度 方法二:利用clear屬性 #d1{ clear: left; /*該標簽的左邊(地面和空中)都不能有浮動的元素*/ } 方法三:使用通用方法 在寫HTML代碼前,先提前寫好處理浮動帶來的影響的css ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在本文中,我們將探討如何使用 CSS 以最少的代碼創造出精美的 CSS 絲帶形狀,並最終實現下麵這個效果: 下麵我們使用html和css來實現這個效果。我們使用內容自適應方式佈局,不用擔心裡面的文字長度。本文介紹兩種絲帶:左側的絲帶稱為“ ...
  • 目錄Vue中的響應式對象獨立的響應式值計算變數監聽響應式變數setup方法 Vue中的響應式對象 Vue3允許在setup()中定義組件需要的數據和方法, 通過return在模板中可以直接使用 reactive方法 <body> <div id = "Application"> </div> <sc ...
  • Effect的概念起源 從輸入輸出的角度理解Effect https://link.excalidraw.com/p/readonly/KXAy7d2DlnkM8X1yps6L 編程中的Effect起源於函數式編程中純函數的概念 純函數是指在相同的輸入下,總是產生相同的輸出,並且沒有任何副作用(si ...
  • 移動互聯網風起雲涌的數十年來,App 似乎成為了企業與用戶打交道最“理所當然”的形式,更年輕一代的用戶甚至可能認為 App 就是一個“與生俱來”的事物,但隨著移動互聯網發展的高峰離去,App 面臨著發展的困境和疲態。最明顯的感知就是這幾年以微信、支付寶、抖音等“超級 App”們大行其道,占據了用戶超... ...
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:佳嵐 回顧傳統React動畫 對於普通的 React 動畫,我們大多使用官方推薦的 react-transition-group,其提供了四個基本組件 Tra ...
  • 常用的物聯網管理系統主要有以下幾種:智能家居系統:通過物聯網技術,將家庭設備和電器互聯起來,實現智能化控制和管理的系統。智能家居系統可以實現家庭設備的遠程式控制制、智能化場景設置、安防監控等功能,方便用戶提高家居生活的便利性和舒適度。智能工廠系統:利用物聯網技術,通過互聯的工廠設備、感測器和電腦系統來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...