大道至简,系统设计和模块划分的实用经验之谈
一、系統(tǒng)設(shè)計
根據(jù)工程實踐經(jīng)驗,系統(tǒng)設(shè)計總體來說可以精簡提煉分為兩個核心階段,即總體設(shè)計和詳細(xì)設(shè)計。
1、總體設(shè)計
總體設(shè)計的主要任務(wù)是把需求分析得到的結(jié)果轉(zhuǎn)換為軟件結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),也就是確定軟件的主體系統(tǒng)結(jié)構(gòu)。
設(shè)計軟件結(jié)構(gòu)的具體任務(wù)是將一個復(fù)雜系統(tǒng)按功能進(jìn)行模塊劃分、建立模塊的層次結(jié)構(gòu)及調(diào)用關(guān)系、確定模塊間的接口和人機(jī)界面等。
概要設(shè)計方法的主要目標(biāo)是根據(jù)特定維度確定各個子系統(tǒng)和模塊的劃分,將由一個或多個功能(或目標(biāo))密切相關(guān)或相似的應(yīng)用程序所組成的程序集合抽象出來。根據(jù)經(jīng)驗概要設(shè)計方法主要包括模塊化方法、功能分解方法、面向數(shù)據(jù)流和面向數(shù)據(jù)結(jié)構(gòu)的設(shè)計方法。按照面向服務(wù)架構(gòu)(SOA)或者比較時髦的觀點,概要設(shè)計的主要工作就是提取和整合微服務(wù)及業(yè)務(wù)邏輯,按照領(lǐng)域抽取展示層,最終拆分出功能獨立的子系統(tǒng)。舉例來說,按照一般的模塊化或者功能拆分方法,我們可以將一個完善的電商系統(tǒng)分解為商品、庫管、訂單、支付、財務(wù)、結(jié)算、配送、搜索、CRM、虛擬貨幣、優(yōu)惠票券、短信、郵件、活動等子系統(tǒng)。而子系統(tǒng)可以再次按照模塊或者功能細(xì)分,比如訂單系統(tǒng)可以按商品品類或者活動類型或者線上線下等維度拆分;支付系統(tǒng)可以按照內(nèi)外部支付方式、支付和風(fēng)控策略、支付模式(如跳轉(zhuǎn)或直連等)等不同維度進(jìn)行劃分。從SOA的角度看,不論子系統(tǒng)劃分維度是什么,SOA都會對各種服務(wù)進(jìn)行布局和整合,發(fā)布服務(wù)和數(shù)據(jù)契約,其最主要的目的就是對子系統(tǒng)服務(wù)進(jìn)行復(fù)用。當(dāng)然,SOA如何和子系統(tǒng)設(shè)計布局和整合聯(lián)系起來這是另一個話題了,本文不展開討論。
2、詳細(xì)設(shè)計
細(xì)節(jié)決定成敗(Idea is cheap,detail is devil.),詳細(xì)設(shè)計是實現(xiàn)系統(tǒng)模塊的關(guān)鍵步驟。
程序=算法+數(shù)據(jù)結(jié)構(gòu),雖然我認(rèn)為這個公式不完全正確,但是突出了算法和數(shù)據(jù)結(jié)構(gòu)的重要性。
詳細(xì)設(shè)計的主要任務(wù)就是根據(jù)總體設(shè)計中確定的業(yè)務(wù)子系統(tǒng),設(shè)計每個子系統(tǒng)功能或模塊的實現(xiàn)算法和數(shù)據(jù)結(jié)構(gòu),但根據(jù)一般的業(yè)務(wù)系統(tǒng)開發(fā)經(jīng)驗,詳細(xì)設(shè)計涉及的具體內(nèi)容可能還包括數(shù)據(jù)庫設(shè)計、界面設(shè)計、子系統(tǒng)互聯(lián)設(shè)計等。
詳細(xì)設(shè)計非常考驗程序員的基本編程水平和經(jīng)驗。我認(rèn)為任何詳細(xì)設(shè)計的最終目標(biāo)都是通過可編程的手段實現(xiàn)軟件系統(tǒng),所以,對于開發(fā)人員,代碼是第一重要的作品,其次才是文檔,手冊,圖表,再其次是PPT等等這些副產(chǎn)品。
在實現(xiàn)業(yè)務(wù)子系統(tǒng)的過程中,必然會涉及到各種方法論,比如面向過程,面向?qū)ο蟮鹊取D敲赐ㄟ^哪種方法論如何實現(xiàn)一個可正常工作功能強(qiáng)大適應(yīng)變化的子系統(tǒng)呢?
在系統(tǒng)具體實現(xiàn)這一塊,我個人接觸最多的是面向?qū)ο缶幊蹋∣OP)。成功設(shè)計開發(fā)一個子系統(tǒng),我的個人開發(fā)經(jīng)驗可以總結(jié)為如下幾條:
a、分而治之,劃分模塊,子系統(tǒng)還可以拆分子系統(tǒng),服務(wù)還可以拆分子服務(wù),這里涉及到一個粒度的問題,非常考驗開發(fā)者的水平和經(jīng)驗,否則很容易過度設(shè)計
b、分層,這個不用說了,如果你真正理解分層的含義,那么在很多情況下,N層不如經(jīng)典三層,誰寫誰知道
c、保證隔離,劃清界限,不要過多假設(shè),不要拖泥帶水,任何模塊或服務(wù)只做它該做的事情
d、實現(xiàn)隔離的最佳方法,就是針對接口,而不是對具體實現(xiàn)編程(Programming to an Interface, not an Implementation)
e、多態(tài),多態(tài),多態(tài),如果一定要復(fù)用類,請優(yōu)先使用對象的組合而非繼承
f、提取變化劇烈的變化點,定期重構(gòu),核心業(yè)務(wù)邏輯必須單元測試
g、UI變化最大,其次業(yè)務(wù)邏輯,而且很多時候UI變化會直接影響后端業(yè)務(wù)邏輯,所以,你的接口設(shè)計要向UI和業(yè)務(wù)邏輯傾斜,反而是基礎(chǔ)框架和基礎(chǔ)服務(wù)非常穩(wěn)定,不需要過度設(shè)計
做到上面這幾點,絕大多數(shù)的開發(fā)問題都會迎刃而解,反正在我多年開發(fā)經(jīng)歷中屢試不爽。
當(dāng)然,歸根結(jié)底,成功的子系統(tǒng)的設(shè)計與開發(fā)還是看具體開發(fā)者的水平,如果邏輯和抽象能力差,或者不認(rèn)真沒有追求看上去就不那么讓人放心,說什么都是白搭。
二、平臺化設(shè)計
我們可以把以提供統(tǒng)一的公共服務(wù)為主要職責(zé)的軟件或系統(tǒng)叫做平臺軟件。比如常見的框架基礎(chǔ)平臺、應(yīng)用管理平臺、工作平臺(OA系統(tǒng)等)、MDM、運(yùn)維平臺、財務(wù)平臺、結(jié)算平臺、支付平臺、配送平臺、決策平臺、客戶管理平臺、CTI平臺、開放平臺、云平臺等等。
縱觀軟件發(fā)展歷程,圍繞著“復(fù)用”,各種方法論和工具層出不窮,比如:結(jié)構(gòu)化開發(fā)中,函數(shù)和過程(表示一段代碼)的復(fù)用;面向?qū)ο笤O(shè)計(OOP)中的類和對象的復(fù)用 ,COM和COM+中的組件標(biāo)志著模塊的復(fù)用;SOA架構(gòu)中某個業(yè)務(wù)服務(wù)(子系統(tǒng))的復(fù)用等等。
主流的軟件開發(fā)模式中,復(fù)用成了系統(tǒng)設(shè)計的一個重要目標(biāo),平臺化是復(fù)用軟件產(chǎn)品的一套成熟解決方案,開發(fā)和運(yùn)營的性價比也較高,而且相對有利于擴(kuò)展。
為什么說平臺化設(shè)計有利于擴(kuò)展呢?下面的段落中我將講一個發(fā)生在自己身上的真實案例。
三、多商戶或多租戶系統(tǒng)
兩年前某司新擴(kuò)張了業(yè)務(wù),大致需求就是相當(dāng)于注冊一個新公司同時該新公司可以使用已有的很多系統(tǒng),但某些核心業(yè)務(wù)(如財務(wù)等)需要獨立運(yùn)營,然后就涉及到我這里說講的多商戶或多租戶的系統(tǒng)。
平臺化的軟件產(chǎn)品有多種多樣,其中,又以多商戶或多租戶的系統(tǒng)設(shè)計與實現(xiàn)最為復(fù)雜,而且隨著需求的變化,擴(kuò)展性很容易成為瓶頸,多商戶或多租戶的系統(tǒng)數(shù)據(jù)存儲我曾經(jīng)有過簡單總結(jié)。
具體到某司的系統(tǒng)擴(kuò)展,我給出的是兩種方案,方案一是可以為新公司獨立部署一套應(yīng)用實例然后修改配置搞定,方案二是可以通過增量增加代碼重新實現(xiàn)一遍已有的功能。
從維持系統(tǒng)穩(wěn)定的角度,兩種方案在理論上而言都相對的不會改動原有系統(tǒng)的實現(xiàn)代碼,第一種直接拷貝原有的部署結(jié)構(gòu)重新實施改改數(shù)據(jù)庫配置就行了,第二種則是不改動任何已有代碼而是通過增加新代碼實現(xiàn)功能(這種不改動任何已有代碼僅限理論上,考慮到業(yè)務(wù)復(fù)雜性,可能還是需要對已有邏輯做些微調(diào))。對于這兩種實現(xiàn)方案,很顯然會有人有不同意見,好了,我知道你們要說重復(fù)是魔鬼,不要重復(fù)你自己等等等等。要是在2010年之前,我一定也有類似的看法,我甚至還可能寫篇博客之類的洋洋灑灑批駁一番,但是經(jīng)過多年工作和編程實踐考驗,再碰到有人說重復(fù)我就呵呵對待了。
無數(shù)事實證明理論和實踐不是一回事,歪果仁也流行說theory is ugly,idea is cheap,talk is very cheap...所以我們需要大膽實踐,驗證口頭上的理論在現(xiàn)實環(huán)境下到底行不行得通。
如果團(tuán)隊人員充足,第一種簡直是為了擴(kuò)展性而量身定做的,看上去只是增加了部署實施和后續(xù)維護(hù)的成本而已。但是如果人員不足,或者變化劇烈系統(tǒng)未來走向依然不確定,從維護(hù)角度,個人倒是傾向選擇第二種方案,因為通過數(shù)據(jù)共享和可擴(kuò)展配置然后只維護(hù)一套系統(tǒng),我實在想不到不使用這種方案更好的理由了。
最終我選擇了第一種方案,一份代碼配置成兩套系統(tǒng)。^_^ Yes,it works.兩個系統(tǒng)目前運(yùn)行穩(wěn)定。
這是我兩年多前近一個月的親身實踐,最大的收獲是,系統(tǒng)實現(xiàn)要高度可配置可運(yùn)維,而且后臺管理工具要開發(fā)完備,一套系統(tǒng)按實例多次部署確實是很有效可行且實惠的解決方案。
四、通用架構(gòu)基礎(chǔ)服務(wù)
在概要設(shè)計和詳細(xì)設(shè)計過程中,不論業(yè)務(wù)、方法論、工具或框架等外部條件怎么變化,從各個(不同)系統(tǒng)中總是可以抽象出公共的相對穩(wěn)定的框架工具或服務(wù),比如分布式緩存服務(wù)、消息隊列服務(wù)、通用數(shù)據(jù)訪問代理DAL(提供訪問數(shù)據(jù)模型和后端數(shù)據(jù)服務(wù)API實現(xiàn)對數(shù)據(jù)庫的一致性訪問,如果分表分庫了,也包括DBRoute功能,不能簡單等同于ORM),企業(yè)服務(wù)總線(ESB)、分布式文件系統(tǒng)、通用日志服務(wù)等等。這些基礎(chǔ)技術(shù)服務(wù)不同于業(yè)務(wù)系統(tǒng),也不同于公共平臺服務(wù)(架構(gòu)基礎(chǔ)服務(wù)可供公共服務(wù)調(diào)用),因為它們和多變的特定業(yè)務(wù)邏輯無關(guān),相對偏重于底層技術(shù),對技術(shù)要求較高,開發(fā)和運(yùn)維這部分服務(wù)的都是水平較高的技術(shù)型選手為主。一般能獨立造輪子出來的公司還是比較有技術(shù)含金量的,雖然我也碰到過只發(fā)明卻不能用或者一用就有無數(shù)坑的團(tuán)隊。我認(rèn)為如果沒有這部分通用架構(gòu)基礎(chǔ)積累,各個子系統(tǒng)各自為戰(zhàn)很可能會造成運(yùn)營和管理上的難題。
總結(jié)
這是我個人從業(yè)10年的系統(tǒng)設(shè)計與開發(fā)經(jīng)驗的粗淺總結(jié),B/S和C/S結(jié)構(gòu)的開發(fā)都通用。在很多人看來可能更多偏重于方法論,我所知道的絕大多數(shù)開發(fā)人員更喜歡討論技術(shù)細(xì)節(jié)的干貨,比如幾年前的自己,更多的偏重于“小節(jié)”,比如記錄學(xué)習(xí)某某編程語言的語法糖,某某流行框架的實踐,某某數(shù)據(jù)庫操作的奇技淫巧,某某算法和數(shù)據(jù)結(jié)構(gòu)的妙用或誤用,某些新技術(shù)的使用經(jīng)驗之類。
但是,我個人認(rèn)為,當(dāng)你真正從專注細(xì)節(jié)的小兵成長為可以獨當(dāng)一面的大將后,你可能也會跳出這些“細(xì)枝末節(jié)”,從系統(tǒng)和架構(gòu)的角度,把握全局,全面看問題。
難忘的2017即將過去,感謝志同道合的人,每一年,我們都要有收獲和進(jìn)步,低頭沉默更堅定。Coding for fun.
祝大家新年快樂。
總結(jié)
以上是生活随笔為你收集整理的大道至简,系统设计和模块划分的实用经验之谈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两台电脑件通过网线进行屏幕扩展
- 下一篇: 知物由学 | 未来50年网络安全行业发展