中小型研發團隊架構實踐:如何規範公司所有應用分層

来源:https://www.cnblogs.com/supersnowyao/archive/2018/01/10/8257937.html
-Advertisement-
Play Games

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


一、寫在前面

     應用分層這件事情看起來很簡單,但每個程式員都有自己的一套,哪怕是初學者。如何讓一家公司的幾百個應用採用統一的分層結構,並得到大部分程式員的認同呢?這可不是件簡單的事情,接下來以我們真實案例與大家一起探討,先問大家兩個技術問題:

     服務的調用代碼你覺得放到哪一層好呢?

  • A 表現層
  • B 業務邏輯層
  • C 數據層
  • D 公共層

     如何組織好 VO(View Object 視圖對象)、BO(Business Object 業務對象)、DO(Data Object 數據對象)、DTO(Data Transfer Object 數據傳輸對象) 呢?

     不同的人會有不同的答案,所以要統一公司應用分層,以減少開發維護學習成本。統一應用分層要可大可小、簡單易用、支持多種場景,我們採用 IPO 方式:I 是 Input、O 是 Output、P 是 Process,一進一齣一處理。應用系統的本質是機器,是處理設備,一進一齣一處理。

                                                                      IPO 原理圖

二、統一邏輯架構

                                                       統一應用分層的邏輯架構圖

職責說明:

  • 文件夾分層法:應用分層採用文件夾方式的優點是可大可小、簡單易用、統一規範,可以包括 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 實體類存放規範以及其命名規則:3、如果請求參數 DTO 實體類、響應 DTO 實體類有基類要繼承,那麼建議為基類取名為 RequestBase.cs、ResponseBase.cs。且這些基類直接放在 DTO 項目的 Common 文件夾下。
    • 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 是記憶體計算邏輯對象,不是業務邏輯層對象,不是只能給業務邏輯層使用 。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的對象轉換。以用戶為中心來設計實體類,可以減少無價值重覆對象和無用轉換。”

     問:應用分層範例代碼的編寫需要註意些什麼?

應用分層範例的代碼要想寫好,非常不容易,很容易引起爭議,很難讓所有人滿意。我們在具體實踐時遵循以下幾點:

應用分層範例的主要價值是明確層的職責和交互,每個層的職責是什麼,哪些要乾,哪些不要乾,以及層與層之間依賴和交互;

私人定製:減少通用幫助類的編寫,如果每一個應用中有大量相同的幫助類,這在架構層面上是有問題。在我們的幾百個線上應用中,儘管減少通用的代碼,包括分頁幫助類、資料庫幫助類、緩存幫助類、MQ 幫助類、日誌幫助類、AOP 幫助類、線程幫助類。業務應用的重點是為業務服務,每一個應用都是特別的,都需要私人定製,極少有通用的代碼,如果有,那麼應該由框架或組件專門解決;

少即是多:應用的場景多,參考人員多,每個人想法不同,牽涉的時間長,所以儘量只做大家都認同的規範、正確的事情,要自底向上、要減少有爭議的代碼範例,否則一個錯誤將會放大百倍、一個有爭議的規範將會很難推行。

追求簡單:代碼編寫可分為三個層次,簡單、複雜、簡單。第一簡單是不知道的簡單,第二個複雜是知道後的複雜,第三個簡單是知道後有取捨的簡單。範例代碼要追求簡單,既可輕鬆擴展支持複雜場景,又要簡單到初級程式員也能操作。

內聚大於解耦:內聚是什麼,內聚是部門內有共同的目標,然後大家緊密合作。解耦是什麼,解耦是部門間各自職責明確,然後減少不必要的連接。一個應用如同一個部門,應有一個共同的目標和職責,然後大家緊密合作。

換句話說,應用內部應減少不必要契約介面(如同公司間才簽約合同),減少不必要的依賴註入實現,減少不必要且代價過大的解耦。一切以簡單實用為主,以應用價值輸出、應用的目標(介面或界面)為導向。

     4.2、Demo 下載

     LayerDemo 下載地址:https://github.com/das2017/LayerDemo

 

文章轉載自:http://www.infoq.com/cn/articles/architecture-practice-12-application-layer?utm_source=infoq&utm_campaign=user_page&utm_medium=link


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

-Advertisement-
Play Games
更多相關文章
  • 1 $(function(){ 2 $(document).bind("click",function(e){ 3 //id為menu的是菜單 4 if($(e.target).closest("#menu").length == 0 && $(e.target).closest("input").... ...
  • 1 var list= $('input:radio[name="name"]:checked').val(); //選擇input中單選name為“name”的並且是選中狀態的 index =$(document).data('index'); //把參數存入document中保存起來併在下一次中... ...
  • nowrap="nowrap" //用於列表中td不許換行 maxlength="100" //用於輸入框的長度限制 colspan="2" //用於td橫向合併 rowspan="2" //用於td縱向合併 style="text-align: center;" //用於字體居中 style="d... ...
  • 表象不同,get把提交的數據url可以看到,post看不到 原理不同,get 是拼接 url, post 是放入http 請求體中 提交數據量不同,get最多提交1k數據,瀏覽器的限制。post理論上無限制,受伺服器限制 get提交的數據在瀏覽器歷史記錄中,安全性不好 場景不同,get 重在 "要" ...
  • 來自:SangSir 鏈接:https://segmentfault.com/a/1190000012673854 原文:https://www.sitepoint.com/shorthand-javascript-techniques/ 1.三元操作符 當想寫 if...else 語句時,使用三元 ...
  • 1、網址 https://mydevice.io/ 2、使用 在mydevice.io上有常見智能手機,PC電腦的尺寸。 ...
  • 集群:高可用,備份,數據可分片 需要運行4個tomcat 1、tomcat埠號(預設占用8005,8009,8080三個埠) tomcat服務 占用埠 tomcat1 6005、6060、6009 tomcat2 7005、7070、7009 tomcat3 8005、8080、8009 to ...
  • 一,idea項目原結構 ics.credit src mian java com.pingan.credit resources config 一系列的配置文件 webapp WEB-INF lib web.xml error.jsp index.jsp 二,idea項目打包後結構 target c ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...