大道至簡,系統設計和模塊劃分的實用經驗之談

来源:https://www.cnblogs.com/jeffwongishandsome/archive/2017/12/31/talk-about-system-design-and-module-division.html
-Advertisement-
Play Games

一、系統設計 根據工程實踐經驗,系統設計總體來說可以精簡提煉分為兩個核心階段,即總體設計和詳細設計。 1、總體設計 總體設計的主要任務是把需求分析得到的結果轉換為軟體結構和數據結構,也就是確定軟體的主體系統結構。 設計軟體結構的具體任務是將一個複雜系統按功能進行模塊劃分、建立模塊的層次結構及調用關係 ...


一、系統設計

根據工程實踐經驗,系統設計總體來說可以精簡提煉分為兩個核心階段,即總體設計和詳細設計。

1、總體設計

總體設計的主要任務是把需求分析得到的結果轉換為軟體結構和數據結構,也就是確定軟體的主體系統結構。

設計軟體結構的具體任務是將一個複雜系統按功能進行模塊劃分、建立模塊的層次結構及調用關係、確定模塊間的介面和人機界面等。

概要設計方法的主要目標是根據特定維度確定各個子系統和模塊的劃分,將由一個或多個功能(或目標)密切相關或相似的應用程式所組成的程式集合抽象出來。根據經驗概要設計方法主要包括模塊化方法、功能分解方法、面向數據流和麵向數據結構的設計方法。按照面向服務架構(SOA)或者比較時髦的觀點,概要設計的主要工作就是提取和整合微服務及業務邏輯,按照領域抽取展示層,最終拆分出功能獨立的子系統。舉例來說,按照一般的模塊化或者功能拆分方法,我們可以將一個完善的電商系統分解為商品、庫管、訂單、支付、財務、結算、配送、搜索、CRM、虛擬貨幣、優惠票券、簡訊、郵件、活動等子系統。而子系統可以再次按照模塊或者功能細分,比如訂單系統可以按商品品類或者活動類型或者線上線下等維度拆分;支付系統可以按照內外部支付方式、支付和風控策略、支付模式(如跳轉或直連等)等不同維度進行劃分。從SOA的角度看,不論子系統劃分維度是什麼,SOA都會對各種服務進行佈局和整合,發佈服務和數據契約,其最主要的目的就是對子系統服務進行復用。當然,SOA如何和子系統設計佈局和整合聯繫起來這是另一個話題了,本文不展開討論。

ArchDesign

2、詳細設計

細節決定成敗(Idea is cheap,detail is devil.),詳細設計是實現系統模塊的關鍵步驟。

程式=演算法+數據結構,雖然我認為這個公式不完全正確,但是突出了演算法和數據結構的重要性。

詳細設計的主要任務就是根據總體設計中確定的業務子系統,設計每個子系統功能或模塊的實現演算法和數據結構,但根據一般的業務系統開發經驗,詳細設計涉及的具體內容可能還包括資料庫設計、界面設計、子系統互聯設計等。

DetailDesign

詳細設計非常考驗程式員的基本編程水平和經驗。我認為任何詳細設計的最終目標都是通過可編程的手段實現軟體系統,所以,對於開發人員,代碼是第一重要的作品,其次才是文檔,手冊,圖表,再其次是PPT等等這些副產品。

在實現業務子系統的過程中,必然會涉及到各種方法論,比如面向過程,面向對象等等。那麼通過哪種方法論如何實現一個可正常工作功能強大適應變化的子系統呢?

在系統具體實現這一塊,我個人接觸最多的是面向對象編程(OOP)。成功設計開發一個子系統,我的個人開發經驗可以總結為如下幾條:

a、分而治之,劃分模塊,子系統還可以拆分子系統,服務還可以拆分子服務,這裡涉及到一個粒度的問題,非常考驗開發者的水平和經驗,否則很容易過度設計

b、分層,這個不用說了,如果你真正理解分層的含義,那麼在很多情況下,N層不如經典三層,誰寫誰知道

c、保證隔離,劃清界限,不要過多假設,不要拖泥帶水,任何模塊或服務只做它該做的事情

d、實現隔離的最佳方法,就是針對介面,而不是對具體實現編程(Programming to an Interface, not an Implementation)

e、多態,多態,多態,如果一定要復用類,請優先使用對象的組合而非繼承

f、提取變化劇烈的變化點,定期重構,核心業務邏輯必須單元測試

g、UI變化最大,其次業務邏輯,而且很多時候UI變化會直接影響後端業務邏輯,所以,你的介面設計要向UI和業務邏輯傾斜,反而是基礎框架和基礎服務非常穩定,不需要過度設計

做到上面這幾點,絕大多數的開發問題都會迎刃而解,反正在我多年開發經歷中屢試不爽。

當然,歸根結底,成功的子系統的設計與開發還是看具體開發者的水平,如果邏輯和抽象能力差,或者不認真沒有追求看上去就不那麼讓人放心,說什麼都是白搭。

 

二、平臺化設計

我們可以把以提供統一的公共服務為主要職責的軟體或系統叫做平臺軟體。比如常見的框架基礎平臺、應用管理平臺、工作平臺(OA系統等)、MDM、運維平臺、財務平臺、結算平臺、支付平臺、配送平臺、決策平臺、客戶管理平臺、CTI平臺、開放平臺、雲平臺等等。

縱觀軟體發展歷程,圍繞著“復用”,各種方法論和工具層出不窮,比如:結構化開發中,函數和過程(表示一段代碼)的復用;面向對象設計(OOP)中的類和對象的復用 ,COM和COM+中的組件標志著模塊的復用;SOA架構中某個業務服務(子系統)的復用等等。

主流的軟體開發模式中,復用成了系統設計的一個重要目標,平臺化是復用軟體產品的一套成熟解決方案,開發和運營的性價比也較高,而且相對有利於擴展。

為什麼說平臺化設計有利於擴展呢?下麵的段落中我將講一個發生在自己身上的真實案例。

 

三、多商戶或多租戶系統

兩年前某司新擴張了業務,大致需求就是相當於註冊一個新公司同時該新公司可以使用已有的很多系統,但某些核心業務(如財務等)需要獨立運營,然後就涉及到我這裡說講的多商戶或多租戶的系統。

平臺化的軟體產品有多種多樣,其中,又以多商戶或多租戶的系統設計與實現最為複雜,而且隨著需求的變化,擴展性很容易成為瓶頸,多商戶或多租戶的系統數據存儲我曾經有過簡單總結。

具體到某司的系統擴展,我給出的是兩種方案,方案一是可以為新公司獨立部署一套應用實例然後修改配置搞定,方案二是可以通過增量增加代碼重新實現一遍已有的功能。

從維持系統穩定的角度,兩種方案在理論上而言都相對的不會改動原有系統的實現代碼,第一種直接拷貝原有的部署結構重新實施改改資料庫配置就行了,第二種則是不改動任何已有代碼而是通過增加新代碼實現功能(這種不改動任何已有代碼僅限理論上,考慮到業務複雜性,可能還是需要對已有邏輯做些微調)。對於這兩種實現方案,很顯然會有人有不同意見,好了,我知道你們要說重覆是魔鬼,不要重覆你自己等等等等。要是在2010年之前,我一定也有類似的看法,我甚至還可能寫篇博客之類的洋洋灑灑批駁一番,但是經過多年工作和編程實踐考驗,再碰到有人說重覆我就呵呵對待了。

無數事實證明理論和實踐不是一回事,歪果仁也流行說theory is ugly,idea is cheap,talk is very cheap...所以我們需要大膽實踐,驗證口頭上的理論在現實環境下到底行不行得通。

如果團隊人員充足,第一種簡直是為了擴展性而量身定做的,看上去只是增加了部署實施和後續維護的成本而已。但是如果人員不足,或者變化劇烈系統未來走向依然不確定,從維護角度,個人倒是傾向選擇第二種方案,因為通過數據共用和可擴展配置然後只維護一套系統,我實在想不到不使用這種方案更好的理由了。

最終我選擇了第一種方案,一份代碼配置成兩套系統。^_^ Yes,it works.兩個系統目前運行穩定。 

這是我兩年多前近一個月的親身實踐,最大的收穫是,系統實現要高度可配置可運維,而且後臺管理工具要開發完備,一套系統按實例多次部署確實是很有效可行且實惠的解決方案。

 

四、通用架構基礎服務

在概要設計和詳細設計過程中,不論業務、方法論、工具或框架等外部條件怎麼變化,從各個(不同)系統中總是可以抽象出公共的相對穩定的框架工具或服務,比如分散式緩存服務、消息隊列服務、通用數據訪問代理DAL(提供訪問數據模型和後端數據服務API實現對資料庫的一致性訪問,如果分表分庫了,也包括DBRoute功能,不能簡單等同於ORM),企業服務匯流排(ESB)、分散式文件系統、通用日誌服務等等。這些基礎技術服務不同於業務系統,也不同於公共平臺服務(架構基礎服務可供公共服務調用),因為它們和多變的特定業務邏輯無關,相對偏重於底層技術,對技術要求較高,開發和運維這部分服務的都是水平較高的技術型選手為主。一般能獨立造輪子出來的公司還是比較有技術含金量的,雖然我也碰到過只發明卻不能用或者一用就有無數坑的團隊。我認為如果沒有這部分通用架構基礎積累,各個子系統各自為戰很可能會造成運營和管理上的難題。

 

總結

這是我個人從業10年的系統設計與開發經驗的粗淺總結,B/S和C/S結構的開發都通用。在很多人看來可能更多偏重於方法論,我所知道的絕大多數開發人員更喜歡討論技術細節的乾貨,比如幾年前的自己,更多的偏重於“小節”,比如記錄學習某某編程語言的語法糖,某某流行框架的實踐,某某資料庫操作的奇技淫巧,某某演算法和數據結構的妙用或誤用,某些新技術的使用經驗之類。

但是,我個人認為,當你真正從專註細節的小兵成長為可以獨當一面的大將後,你可能也會跳出這些“細枝末節”,從系統和架構的角度,把握全局,全面看問題。

難忘的2017即將過去,感謝志同道合的人,每一年,我們都要有收穫和進步,低頭沉默更堅定。Coding for fun.

祝大家新年快樂。


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

-Advertisement-
Play Games
更多相關文章
  • 一.HTML簡單介紹: HTML是Hypertext Markup Language的英文縮寫,即超文本標記語言。 它是一種標記語言而非編程語言,由瀏覽器解釋支持。 html文件是一種文本文件,可以用記事本打開,當然也可以用其他開發工具,比如dreamweaver和VS等等。通過在文本中添加各種標簽 ...
  • 現在我們的Redux和React Redux已經基本實現了,在Redux中,觸發一個action,reducer立即就能算出相應的state,如果我要過一會才讓reducer計算state呢怎麼辦?也就是我們如何實現非同步的action呢?這裡就要用到中間件(middleware) 1. 中間件(mi ...
  • CSS vs. JS Animation: 哪個更快? CSS vs. JS Animation: 哪個更快? 基於JavaScript的動畫竟然已經默默地比CSS的transition動畫快了?而且,Adobe和 Google竟然一直在發佈可以媲美原生應用的富媒體移動站點? 這篇文章將會逐點講解基 ...
  • 使用WebGL + Three.js製作動畫場景 3D圖像,技術,打造產品,還有互聯網:這些只是我愛好的一小部分。 現在,感謝WebGL的出現-一個新的JavaScriptAPI,它可以在不依賴任何插件的情況下渲染瀏覽器中的3D圖像-這讓3D渲染操作變得異常簡單。 隨著虛擬現實和增強現實應用的發展, ...
  • MobX入門 本文嘗試解釋MobX是如何運作的。我們將用MobX創建一個小案例。如果你正在找靠譜的MobX文檔,可以去看 "官方文檔" 。 什麼是MobX 官方文檔的解釋:簡潔,易擴展的狀態管理。簡單來說,MobX可以很好的管理應用程式的狀態/數據,同時又簡潔,易擴展。先來看一張圖: 我們通過上圖的 ...
  • 七牛雲儲存 nodejs qiniu 模塊 信息配置 文件路徑formUploader.putFile方法 文件位元組方法formUploader.put ** 該方法七牛不支持 buffer類,可使用Buffer.toString()進行轉換 可讀流上傳方式formUploader.putStrea ...
  • 自從上次分享《Redis到底該如何利用?》已經有1年多了,這1年經歷了不少。從碼了我們網站的第一行開始到現在,我們的緩存模塊也不斷在升級,這之中確實略有心得,最近也有朋友探討緩存,覺得可以總結並分享一下拙見,期待能有更深入的研究。 緩存是什麼? 我時常在群里或者在社區里看到有人對緩存有諸多疑問,搞不 ...
  • # 關於後端架構設計 關註了大半年的微服務架構,現在感覺有些力不從心。IT行業的技術累積,需要時間和不斷沉澱。 對於服務架構方面設計,這一年心路成長歷程: 支付寶 先看看業內最強的支付寶系統,支付寶的支付系統整體架構設計 京東金融 來自京東支付平臺總體架構設計 京東金融是在網銀線上的基礎上發展起來的 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...