編程心智(一)——代碼架構與系統架構

来源:http://www.cnblogs.com/gujf2016/archive/2017/09/27/7604104.html
-Advertisement-
Play Games

原文地址: http://michael-j.net/2017/09/24/%E7%BC%96%E7%A8%8B%E5%BF%83%E6%99%BA-%E4%B8%80-%E2%80%94%E2%80%94%E4%BB%A3%E7%A0%81%E6%9E%B6%E6%9E%84%E4%B8%8E%E ...


原文地址: http://michael-j.net/2017/09/24/%E7%BC%96%E7%A8%8B%E5%BF%83%E6%99%BA-%E4%B8%80-%E2%80%94%E2%80%94%E4%BB%A3%E7%A0%81%E6%9E%B6%E6%9E%84%E4%B8%8E%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/

 

寫在開頭的話

想寫這個系列文章很久了,但是對於一個重度的拖延症患者來說,決定寫一個系列文章還是頗有挑戰。最開始,只想寫一兩片文章分享一下自己對於編程的感悟。但隨著時間越拖越久,發現想寫的東西越來越多。直到今天,居然發現我的博客的To-Do-List(目前我在使用WunderList,很好用的一個To-Do-List工具)文章數達到了10篇,終於說服自己動筆了。
“編程心智”這個詞這段時間一直縈繞在我的腦海中,我覺得這個詞最能表達我想分享了內容了。我希望通過這個系列文章分享自己對於代碼、編程、架構以及軟體工程的理解與感悟,另外,還有隱藏在代碼後面的程式員心智。所有文章僅代表個人觀點,沒有是非對錯的標準。如果你對文章中的觀點不認同,還請給我留言,不同的聲音對於進步有著極大的促進。

選擇“代碼架構與系統架構”作為第一篇文章是因為我發現很多人對“架構”的誤解很深,而且國內關於“代碼架構”的分享和書籍鳳毛麟角,似乎只有流弊的“系統架構”才能成為談資。我不太能理解這個現象,好像大部分人都完全不用操心“如何寫好代碼”這回事,似乎只要有一個看上去比較“完美”的系統架構就能解決所有的事情。但根據我的實際經驗,現實情況往往不是這樣,有時候甚至相反。有些項目的系統架構圖畫的非常“漂亮”,引入了很多新潮的技術,每個組件都劃分的很清楚,系統之間如何通信,模塊之間如何引用等等都一目瞭然。但是當你去看項目的真實代碼時,完全是另外一番景象。至於為什麼會這樣,我想很大一部分原因是“系統架構圖”已經淪為了一種滿足KPI考核手段,而通常你的老闆不會深入地去理解你的代碼,更不要說指出其中的問題了。

系統架構

相信很多人對系統架構都不陌生,只要是從事軟體開發領域的人,或多或少都接觸過系統架構。系統架構最直觀的表現就是系統架構圖,下圖就是一張系統架構圖,摘自李智慧老師大型網站技術架構:核心原理與案例分析

部署架構圖

部署架構圖

系統架構是一個比較大的概念,從技術角度來看,它往往以部署架構圖的形式出現(上圖就是);而換到業務視圖,它又以另外一種形式出現,如下圖。

業務架構圖

業務架構圖

不論是部署架構圖還是業務架構圖,它們都反映了系統與系統之間的一種關聯關係,從更加巨集觀的角度反映系統在全局中的作用和定位。如果你是某個系統的開發者或者負責人,那麼你的系統會在系統架構圖中以一個方框出現。通過系統架構圖,你的老闆和同事能很直觀地瞭解到你的系統在全局中的位置以及你服務的層次。這樣做有好處的,它降低了技術人員之間以及技術和業務人員之間地溝通成本。

實際上,關於系統採用什麼樣的中間件、何種資料庫和緩存、選用哪種服務框架等等,甚至今年非常火的微服務架構,這些統統都屬於系統架構的範疇。關於系統架構方面的書籍和文章已經非常多了,而且國內的分享也主要集中於此,我就不再這方面展開了。

代碼架構

相比於系統架構,代碼架構對很多人可能就陌生許多。我剛剛去Google一下,發現甚至沒有關於“代碼架構”的權威定義。那麼什麼是代碼架構呢?打個比方,如果你的系統在系統架構圖中只是一個方框,那麼代碼架構就是介紹這個方框是如何組成和實現的。代碼架構的關註點在一個工程(Project)內部,它描述了你的整個工程代碼是如何組織和實現的。簡而言之,系統架構是巨集觀層面的體現,而代碼架構是微觀層面的體現。

在我的博客中有很多關於DDD的文章,而DDD本身就是一種代碼架構。除此之外,還有MVC、CQRS、Event Souring等等。那麼,設計模式是否也可以成為代碼架構呢?在某種程度上是的,因為它可以指導你如何組織代碼的實現,如何在代碼層面解耦,但是,光光通過設計模式你無法組織起你的整個工程代碼,所以從嚴格意義上講,設計模式並不是一種代碼架構。代碼架構也可以通過圖文的形式表現,不過這完全取決於你採用何種代碼架構。下圖是我目前負責的一個系統的代碼架構,這個系統的核心在於策略語言(Policy)。

六邊形架構

六邊形架構

熟悉DDD的人一眼就可以看出來這是DDD種的經典六邊形架構(題外話,至今我不太明白為什麼是六邊形)。如果你的工程採用MVC或者CQRS架構進行組織,可能會畫出完全不一樣的架構圖。我很慶幸,在我正式的職業編程生涯的早期接觸到了DDD這種編程思想,它對我的編程生涯影響很大,讓我少走了很多彎路。如果你還沒有接觸過DDD,我希望你能立馬買一本Eric Evans領域驅動設計:軟體核心複雜性應對之道,細細研讀此書,字裡行間都體現著作者對軟體開發的深刻理解。

為什麼我說代碼架構是如此的重要?是因為其奠定了大型系統的基石。我認為衡量一個優秀的程式員的能力之一就包含其對複雜問題的解決能力。現實的問題往往比理論複雜很多,很多時候需要妥協、折中、權衡和取捨,如何在這些取捨之中不影響到軟體的核心,這需要大量的經驗。當然,這是有規律可循的,那就是代碼架構。

好的代碼架構會幫助你理解你的業務,哪些部分是你系統的核心,哪些部分只是技術層面的實現。換句話說,好的代碼架構不光能知道你如何去組織你的代碼,還能加深你對系統的理解。反過來,隨著你對系統理解的不斷深入,你又能更好的調整你的代碼以適應新的變化。是不是所有的項目都需要代碼架構呢?這取決於你的問題域。如果你的項目僅僅是一個Hello World程式,又或者是一個數據採集腳步,那麼使用代碼架構來組織代碼可能沒什麼作用,反而使得你的代碼變得更加複雜和臃腫。那麼什麼情況下你需要使用代碼架構呢?我認為只要滿足以下兩個條件就行。

  • 你有一個相對固定的業務場景。固定意味著你要處理的問題域是有邊界的,比如訂單系統、庫存系統、用戶中心等等,它們所要處理的問題是比較集中和固定的。

  • 你要解決的問題相對比較複雜。這看上去本身就比較矛盾,因為“複雜”本身就是相對的。這裡的複雜的意義在於,你要處理的問題領域本身就具有複雜性。也許起初問題本身並不複雜,但隨著時間的推移,系統要處理的問題也越來越複雜了,這要求你對問題有一定的前瞻性。

事實上,上面兩個條件是很容易滿足,之所以還列出來因為在實際的開發過程中,我確實遇到過在以上兩點犯錯的情況。這主要出現在剛剛開始正式編程生涯的畢業生,他們對業務和要做的事理解程度不夠,如果有經驗豐富的程式員帶的話,可以避免走一些彎路。正是因為上訴條件門檻較低,所以代碼架構的應用場景非常廣泛。有可能你現在的項目就在使用MVC架構,只是你沒有意思到。我建議程式員能有意識地去瞭解你的代碼架構,深入的思考一下目前的代碼組織方式是最為合理的嗎?

小結

說了這麼多,希望自己把代碼架構和系統架構的核心點說明白了。兩者都非常地重要,但是應用的場景各不相同,兩者結合使用才能讓你做出一個高質量的系統。相比於系統架構,代碼架構往往被人們所遺留,但這並不代表其不重要。依我之見,代碼架構的應用場景更為廣泛,因為大部分的公司和項目其實並不需要一個複雜和“高大上”的系統架構,而與我們日常交互最多的就是一行一行的代碼。深入的瞭解你的項目代碼是如何組織對程式員來說是十分重要的,好的代碼架構能起到事半功倍的效果。最後,個人建議將代碼架構納入到KPI的評判之中,最為直觀的表現就是“技術債務”。好的代碼架構會把項目的技術債務維持在一個比較低的水平;相反,糟糕的代碼結構會讓項目的“技術債務”越滾越大,最終到了不可收拾的程度。不過,技術債務如何量化,以及是否需要量化,目前這方面有著很多不同的身影,但是,能意識到這個問題的存在,至少,我們在向高水平的軟體開發者邁出了一大步。

寫在最後的話

編程心智這個系列我會持續地更新,但更新時間就不確定了。前面也說了,我是一個重度的拖延症患者,而且,最近項目的事情很多,一個接著一個。我會努力做到一個月一篇的。


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

-Advertisement-
Play Games
更多相關文章
  • springMVC中對HTTP請求form data和request payload兩種數據發送塊的後臺接收方式 ...
  • 簡單工廠模式:由一個工廠對象決定創建出哪一種類的實例。 1.抽象類 2.具體類 3.具體類 4.工廠 5.測試代碼 工廠方法模式:定義一個用於創建對象的介面,讓子類去決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。 1.抽象工廠 2.抽象產品和具體實現類。 3.具體工廠,用來具體實現哪個產 ...
  • 專業定製仿百度文庫網站系統,仿豆丁網網站,仿道客巴巴網站,文庫網站系統源碼,文庫網站建設開發,支持電腦版+手機版+微信版+小程式版+APP版,由10年的技術團隊專業定製,需要的朋友可以聯繫我們。 網站採用:PHP+MySQL+thinkPHP框架(可定製) <ignore_js_op> <ignor ...
  • 所謂素數是指除了1和它本身以外,不能被任何整數整除的數,例如17就是素數,因為它不能被2~16的任一整數整除。因此判斷一個整數m是否是素數,只需把m被2~m-1之間的每一個整數去除,如果都不能被整除,那麼m就是一個素數另外判斷方法還可以簡化。m不必唄2~m-1之間的每一個整數去除,只需被2~√m之間 ...
  • 修改表 修改表 語法: Alter table <舊表名> rename [ TO] <新表名>; 例子:Alter table `demo01` rename `demo02`; 添加欄位 語法: Alter Table 表名 ADD 欄位名 數據類型 [屬性]; 例子:Alter Table ` ...
  • 第一部分說明 第一部分大概有20來章,主要講的是一些開發常識、開發前中後期準備內容、開發環境與伺服器部署環境安裝設置、python基礎框架結構與功能等內容,代碼會比較簡單。 本系列會以故事的方式,向大家描述一位有點開發基礎的程式猿,怎麼將一個小系統,根據需求的增加,以及對技術的追求,慢慢的通過重構, ...
  • 項目結構 在目錄中運行 ant war 即可. ...
  • 本來應一個可愛帥氣的編輯之邀,要寫一本書《靜兒的互聯網服務治理私房菜》。想選服務治理的題材,想急著簽協議就寫了一個很匆忙的目錄和例章。寫書本是計划了很久的一件事情。現在反而有些猶豫了。我是不是應該把腳步放慢一些,再穩一些。我是不是應該自己先寫了一部分,再考慮簽約出版的事情。要做的事情太多了,比如:家 ...
一周排行
    -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 ...