中小研發團隊架構實踐之統一應用分層

来源:https://www.cnblogs.com/dotnet-arch-system/archive/2018/01/31/8395207.html
-Advertisement-
Play Games

一、寫在前面 應用分層這件事情看起來很簡單,但每個程式員都有自己的一套,哪怕是初學者。如何讓一家公司的幾百個應用採用統一的分層結構,並得到大部分程式員的認同呢?這可不是件簡單的事情,接下來以我們真實案例與大家一起探討,先問大家兩個技術問題: 服務的調用代碼你覺得放到哪一層好呢?A表現層;B業務邏輯層 ...


一、寫在前面

應用分層這件事情看起來很簡單,但每個程式員都有自己的一套,哪怕是初學者。如何讓一家公司的幾百個應用採用統一的分層結構,並得到大部分程式員的認同呢?這可不是件簡單的事情,接下來以我們真實案例與大家一起探討,先問大家兩個技術問題:
  1. 服務的調用代碼你覺得放到哪一層好呢?A表現層;B業務邏輯層;C數據層;D公共層。
  1. 如何組織好VO(View Object視圖對象)、BO(Business Object業務對象)、DO(Data Object數據對象)、DTO(Data Transfer Object數據傳輸對象)呢?
不同的人會有不同的答案,所以要統一公司應用分層,以減少開發維護學習成本。統一應用分層要可大可小、簡單易用、支持多種場景,我們採用IPO方式:I是Input、O是Output、P是Process,一進一齣一處理。應用系統的本質是機器,是處理設備,一進一齣一處理。                                                                   IPO原理圖

二、統一邏輯架構

                                         統一應用分層的邏輯架構圖 職責說明:
層英文名 中文名 說明  
PresentationLayer 表現層文件夾 上層向用戶提供服務,負責視圖展示。項目類型包括WebSite、WebForm、MVC、WCF、WebService等。  
BusinessLayer 業務邏輯層文件夾 中間邏輯處理,負責應用系統的業務邏輯的處理。  
DataLayer 數據訪問層文件夾 下層調用服務,負責數據資源提供方如資料庫、SOA、OpenAPI的交互。  
EntityLayer 實體層文件夾 VO:View Object視圖對象;
DTO:Data Transfer Object數據傳輸對象;
BO:Business Object業務對象;
DO:Data Object數據對象;
在實際項目中,為簡化設計可進行裁剪,BO和DO為可選,DTO屬於服務項目類型,VO屬於網站項目類型,也不會同時存在。
 
CommonLayer 公共層文件夾 工具類庫,負責提供應用系統中常用的操作。  
TestLayer 測試層文件夾 單元測試(可選),負責對其它類庫的自動化單元測試。  
       
  • 文件夾分層法:應用分層採用文件夾方式的優點是可大可小、簡單易用、統一規範,可以包括5個項目,也可以包括50個項目,以滿足所有業務應用的多種不同場景;
  • 調用規約:在開發過程中,需要遵循分層架構的約束,禁止跨層次的調用;
  • 下層為上層服務:以用戶為中心,以目標為導向。上層(業務邏輯層)需要什麼,下層(數據訪問層)提供什麼,而不是下層(數據訪問層)有什麼,就向上層(業務邏輯層)提供什麼;
  • 實體層規約:DO是數據表對象,不是數據訪問層對象,不是只能給數據訪問層使用;DTO是網路傳輸對象,不是表現層對象,不是只能給表現層使用;BO是記憶體計算邏輯對象,不是業務邏輯層對象,不是只能給業務邏輯層使用 。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的對象轉換。以用戶為中心來設計實體類,可以減少無價值重覆對象和無用轉換;
  • U型訪問:下行時表現層是Input,業務邏輯層是Process,數據訪問層是Output。上行時數據訪問層是Input,業務邏輯層是Process,  表現層就Output。

三、我們的具體規範

        此規範我們用了四年,牽涉幾百個應用,200多個研發人員,是一個成功的實踐。接下來就借用本文提供下載的TripOrderService、TripSellerMVCSite這兩個Demo來進行具體規範的說明,以下是截圖:

3.1、項目命名規則

項目命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.{項目職責英文名全稱},如:Trip.Seller.DTO。

3.2、業務邏輯層的項目規範

規範說明: 1、項目名的命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.xxxBusiness,如上圖的Trip.Order.Business。 2、類名以Logic結尾,如上圖的OrderLogic.cs。

3.3、數據操作項目規範

規範說明: 1、各數據操作項目名根據使用什麼資料庫進行分類,然後以DB為結尾,具體命名規則是:{產品線英文名全稱}.{子系統英文名全稱+應用名}.{使用什麼資料庫}DB,如上圖的Trip.Seller.MSSQLDB。 2、如果涉及到多個資料庫訪問的,那麼數據操作項目下的類文件需要按資料庫名稱(以DB為結尾)創建文件夾分開,如上圖的TripOrderDB文件夾。 3、建議在應用中使用SQL語句,不使用存儲過程。在資料庫中不新增存儲過程,但舊的存儲過程可以繼續使用和修改。 4、分頁建議使用資料庫(如SQLServer)的最新特性進行分頁,並將每個分頁SQL直接寫到應用中。

3.4、實體類項目規範

  • 數據傳輸對象DTO規範

規範說明: 1、DTO項目命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.DTO,如上圖的Trip.Order.DTO 2、請求參數DTO實體類、響應DTO實體類存放規範以及其命名規則:       a、請求參數DTO實體類放在Request文件夾下,且命名規則為:以Request結尾,如上圖的SearchOrderRequest.cs。        b、響應DTO實體類放在Response文件夾下,且命名規則為:以Response結尾,如上圖的SearchOrderResponse.cs。        c、如果請求參數DTO實體類或響應DTO實體類的屬性中有對象或枚舉,那麼這些對象所屬的類、枚舉放在DTO項目的Common文件夾下。 3、如果請求參數DTO實體類、響應DTO實體類有基類要繼承,那麼建議為基類取名為RequestBase.cs、ResponseBase.cs。且這些基類直接放在DTO項目的Common文件夾下。
  • 視圖對象VO規範

規範說明: 1、VO項目命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.ViewModel,如上圖的Trip.Seller.ViewModel。 2、各VO實體類,我們用Controller名作為文件夾名進行分開,如上圖的Order文件夾。 3、VO實體類名的命名建議:      a、請求參數VO實體類以Input/Form/Query結尾,如上圖的SearchOrderInput.cs。      b、響應VO實體類以Output/List/Result結尾,如上圖的SearchOrderOutput.cs。
  • 業務對象BO規範(可選)

BO實體類名以Model為結尾: 規範說明: 1、BO項目命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.BO,如上圖的Trip.Order.BO; 2、以Model結尾,如上圖的OrderModel.cs; 3、為了簡化設計,BO項目為可選,可在DO項目里建文件夾。
  • 數據對象DO規範(可選)

規範說明: 1、DO項目命名規則:{產品線英文名全稱}.{子系統英文名全稱+應用名}.Entity,如上圖的Trip.Seller.Entity; 2、如果涉及到多個資料庫訪問的,那麼需要按資料庫名稱(以DB為結尾)創建文件夾分開,如上圖的TripOrderDB文件夾; 3、表名+Entity結尾,如上圖的OrderEntity.cs; 4、DO是數據表對象,供單表CURD操作。對於多表查詢請求對象和返回對象,可定義新對象或使用現有對象(DTO/BO)來完成。

3.5、資料庫連接配置規範

規範說明: 1、資料庫連接的配置必須讀寫分離。 2、資料庫連接字元串建議加密處理。 3、資料庫連接配置名的命名規則:{以DB為結尾的資料庫名稱}_讀寫類型,如: TripOrderDB_SELECT、TripOrderDB_INSERT。

3.6、配置文件方面的規範

規範說明: 1、所有配置文件(除Web.config文件外)都必須放到Config文件夾下。 2、所有配置文件(除Web.config文件外)按不同環境區分開,具體命名規則是:{功能模塊英文名}.{環境英文簡稱名}.config,其中本地環境的英文簡稱名是Dev,測試環境的英文簡稱名是Test,正式環境的英文簡稱名是Prod,如上圖的AppSetting.Dev.config。 3、保持Web.config配置文件的乾凈,只留環境設置節點。

3.7、靜態資源文件方面的規範

規範說明: 1、公共的靜態資源文件(css、js、image等)放在另外的靜態站點中,統一由前端進行開發和維護。一般,css文件放在css文件夾下,js文件放在js文件夾下,image圖片文件放在img文件夾下。 2、與某項業務有關的js文件可以放到各自業務項目的表現層PresentationLayer下,以方便開發人員調試,js文件可放在項目的js文件夾下。 3、靜態資源文件必須使用版本號管理,以防更新後由於客戶端瀏覽器緩存而導致站點使用的依然是舊版本的靜態資源文件:
<script src="~/js/[email protected]"></script>

四、寫在最後

4.1、問題回答

問:服務的調用代碼應該放到哪一層呢? A表現層、B業務邏輯層 、C數據層、D公共層。 答:我們的規範是統一放到數據資源訪問層即C。上層提供服務,下層調用服務,中間處理業務邏輯。   問:如何組織好VO(View Object視圖對象)、BO(Business Object業務對象)、DO(Data Object數據對象)、DTO(Data Transfer Object數據傳輸對象)呢? 答:通常有兩種做法,限定訪問範圍和不限定訪問範圍,實際項目中可根據需要選擇、折中或裁剪。我們使用後者,將EntityLayer作為通用對象放到左側,具體可參考實體層規約:“DO是數據表對象,不是數據訪問層對象,不是只能給數據訪問層使用;DTO是網路傳輸對象,不是表現層對象,不是只能給表現層使用;BO是記憶體計算邏輯對象,不是業務邏輯層對象,不是只能給業務邏輯層使用 。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的對象轉換。以用戶為中心來設計實體類,可以減少無價值重覆對象和無用轉換。”   問:應用分層範例代碼的編寫需要註意些什麼? 答:應用分層範例的代碼要想寫好,非常不容易,很容易引起爭議,很難讓所有人滿意。我們在具體實踐時遵循以下幾點:
  1. 應用分層範例的主要價值是明確層的職責和交互,每個層的職責是什麼,哪些要乾,哪些不要乾,以及層與層之間依賴和交互;
  1. 私人定製:減少通用幫助類的編寫,如果每一個應用中有大量相同的幫助類,這在架構層面上是有問題。在我們的幾百個線上應用中,儘管減少通用的代碼,包括分頁幫助類、資料庫幫助類、緩存幫助類、MQ幫助類、日誌幫助類、AOP幫助類、線程幫助類。業務應用的重點是為業務服務,每一個應用都是特別的,都需要私人定製,極少有通用的代碼,如果有,那麼應該由框架或組件專門解決;
  1. 少即是多:應用的場景多,參考人員多,每個人想法不同,牽涉的時間長,所以儘量只做大家都認同的規範、正確的事情,要自底向上、要減少有爭議的代碼範例,否則一個錯誤將會放大百倍、一個有爭議的規範將會很難推行。
  1. 追求簡單:代碼編寫可分為三個層次,簡單、複雜、簡單。第一簡單是不知道的簡單,第二個複雜是知道後的複雜,第三個簡單是知道後有取捨的簡單。範例代碼要追求簡單,既可輕鬆擴展支持複雜場景,又要簡單到初級程式員也能操作。
  1.  內聚大於解耦:內聚是什麼,內聚是部門內有共同的目標,然後大家緊密合作。解耦是什麼,解耦是部門間各自職責明確,然後減少不必要的連接。一個應用如同一個部門,應有一個共同的目標和職責,然後大家緊密合作。換句話說,應用內部應減少不必要契約介面(如同公司間才簽約合同),減少不必要的依賴註入實現,減少不必要且代價過大的解耦。一切以簡單實用為主,以應用價值輸出、應用的目標(介面或界面)為導向。

4.2、Demo下載

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

-Advertisement-
Play Games
更多相關文章
  • 簡介:模態框(Modal)是覆蓋在父窗體上的子窗體。通常,目的是顯示來自一個單獨的源的內容,可以在不離開父窗體的情況下有一些互動。子窗體可提供信息、交互等。 Modal簡介 Modal實現彈出表單 Modal實現刪除提示框 其他用法 Bootstrap 模態框(Modal)插件 模態框(Modal) ...
  • 申請百度統計後,會得到一段JS代碼,需要插入到每個網頁中去,在Vue.js項目首先想到的可能就是,把統計代碼插入到index.html入口文件中,這樣就全局插入,每個頁面就都有了;這樣做就涉及到一個問題,Vue.js項目是單頁應用,每次用戶瀏覽網站時,訪問內頁時頁面是不會刷新的,也就意味著不會觸發百 ...
  • border屬性 border-width border-style border-color inherit border-style的值:none dotted(點線) dashed(虛線) solid(實線) double(雙線) groove(凹槽) ridge(凸起) inset outs ...
  • 強制類型轉換 將值從一種類型轉換為另一種類型通常稱為類型轉換,這是顯式的情況。隱式的情況被稱為強制類型轉換 在書中,作者還提出一種區分方式: 類型轉換髮生在靜態類型語言的編譯階段,強制類型轉換髮生在動態類型語言的運行時。 JS天生的動態類型語言,所以JS中統一講強制類型轉換。 一、JS中的強制類型轉 ...
  • font連寫屬性 font-style font-variant font-weight font-size/line-height font-family font-size與font-family為必填 font-style 可指定的值為: normal(正常) italic(斜體) obliq ...
  • .toggle-cart-enter-active, .toggle-cart-leave-active { transition: all .3s ease-out; } .toggle-cart-enter, .toggle-cart-leave-active { transform: tran ...
  • wx-jq (一套完全原創的微信小程式插件集合庫) 微信小程式插件,微信小程式組件,微信小程式插件集合,微信小程式組件集合,微信小程式插件學習,微信小程式插件開發, 線上演示: 下載地址: https://gitee.com/dgx/wx-jq 效果展示(截圖大部分來自真機蘋果5s,少量來自模擬器) ...
  • 一個插排引發的設計思想 (一) 觀察者模式 一個插排引發的設計思想 (二) 抽象類與介面 一個插排引發的設計思想 (三) 委托與事件 ...待續.... 前兩篇文章循序漸進的介紹了觀察者模式、抽象類和介面, 並分析了抽象類和介面的不同. 結尾處有這樣的問題: 無論是抽象類還是介面, 都是將設備本身放 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...