国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

你的分層架構還好嗎?

開發 架構
當我們開始一個新的項目,我們就開始創建一個個折文件夾。哦,不對,那我們在做分層架構設計。架構最后落到現有的計算機操作系統上,其的展示形式是分層架構。畢竟,硅基不如碳基。

 分層架構,不就是建文件夾的藝術嗎?

[[285132]]

注:本文更適用于中大型項目,小項目開心就好了。因為時代的原因,對部分詞匯描述可能不是那么準確,歡迎指正。

當我們開始一個新的項目,我們就開始創建一個個折文件夾。哦,不對,那我們在做分層架構設計。架構最后落到現有的計算機操作系統上,其的展示形式是分層架構。畢竟,硅基不如碳基。

可是呢,為什么我們要做分層架構設計呢?通過層(Layer)來隔離不同的關注點。

So,我要開始瞎扯了。

基本思想:關注點分離,劃分邊界

注:三層架構(controller-service-model)并非等于于 MVC 架構模式。對于其的錯誤等同,導致了架構上的一系列錯誤。

 

問題:落后的三層架構

過去,我總以為對于大部分項目來說,三層分層架構之外的部分是大泥球,即隨意化的代碼組織方式。然而,我發現對于大部分的項目來說,三層分層架構的 service 也是個大泥球,我忘記了三層分層架構的 model 層也是一堆大泥球。Controller 相對好一點,但是對于某些項目來說也是個小泥球。

大泥球是指一個隨意化的雜亂的結構化系統,只是代碼的堆砌和拼湊,往往會導致很多錯誤或者缺陷。

在今天 DDD + 整潔架構流行的今天, 三層分層架構已經完全不能滿足現有應用的需求,甚至看上去一團糟糕。它存在這么一些問題:

  1. 統一管理是魔鬼,如 controller 文件夾下一堆的代碼,到處亂放的 model。
  2. 缺乏明確的職責劃分,如 controller 承擔了 service 的職責
  3. 臃腫的 service,和貧血的 model
  4. 三層分層之后的隨意文件組織方式,如 kafka 等到處亂放的代碼
  5. ……

可是,為什么會這樣呢?

  1. 職責(or 限界上下文)沒有劃分明確和清晰
  2. model 層存在大量的二義性
  3. 技術導向架構模式
  4. ……

于是,我們有了一些基本的解決方案,或者說是套路。

重新定義:消除二義性

 

當我們談論 service 的時候,我們談論的是同一個 service 嗎?

當我們談論 model 的時候,我們談論的是同一種 model 嗎?

若對于一個文法的某一句子存在兩棵不同的語法樹,則該文法是二義性文法。

如果有多種不同類型的類,都被放置在 model 包下。那么,你應該消除 model 這個包,改為更表意的名稱,如 Entity、* Request、* Response 等等。同理,一旦你們展開對某個名稱的討論時,是時候好好考慮其中的二義性。

最后,你還需要有一個相關領域的名詞表。

劃分邊界:業務導向架構

開始之前不得不說的是:

  • 微服務是一種業務導向架構。
  • 微服務是一種業務導向架構。
  • 微服務是一種業務導向架構。

所以,如果你的微服務劃分出現了不同的幾個技術維度的服務,那么你需要好好反思一下。

So,為了迎接業務導向架構,我們需要以采用水平 + 垂直架構的方式來重新劃分架構,將各業務模板的代碼聚合到各自的業務模板中,順便把大量地 util 和 common 內聚到服務中。而它們都基于其它低層模板。

隨后,我們還可以嘗試將單體應用拆分到微服務。

但是,我們都不應該依賴于低層模塊,于是就有了……。

關注點分離:針對接口編程

我們看到了整潔架構:

 

在其中有一個非常重要的原則:

依賴倒置原則:高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象。

這一點在大部分的項目中,已經實踐得相關的好。畢竟,有各種各樣的 * Service + * ServiceImpl。

除此,為了實現這樣的目標,對于采用 DDD 架構的應用來說,在我們的 domain 層的限界上下文,除了包含自身的 entity、vo 等,它應該還帶有 repository 的抽象。這樣一來,我們的 domain 層便不依賴

應用分層:DDD 與整潔架構

 

所以,讓我們來看個問題。這是一個在 GitHub 上 star 數接近 15K 的 Java 語言編寫的開源 CMS 中,某個模塊的代碼目錄:

  1. ├── cms-admin/ 
  2. ├── cms-common/ 
  3. ├── cms-dao/ 
  4. ├── cms-job/ 
  5. ├── cms-rpc-api/ 
  6. ├── cms-rpc-service/ 
  7. ├── cms-search/ 
  8. └── cms-web/ 

這是一個技術導向的應用架構。所以,當我要新加一個功能的時候,我需要:

  1. 在 cms-dao 模塊中加一個 model 和一個 mapper
  2. 在 cms-rpc-service 模塊中加一個 service
  3. 在 cms-web 模塊中中加一個 controller

“完美”,沒有什么問題啊。

而隨著時間的推移,你現在已經有一個巨大無比的 model 層,修改代碼時需要在不同的模塊跳轉。而不能快速修改相關的代碼。甚至于,你無法采用微服務架構,你是一個巨大的單體應用。

為了挽救這樣的一個項目,我們不得不嘗試做一些事情。

切割基礎設施

 

你的基礎設施自開發完成之后,基本不變,而你的業務代碼一直在發生變化。

引起技術實現發生變化的原因與引起領域邏輯發生變化的原因顯然不同,這就導致基礎設施和領域邏輯問題會以不同速率發生變化。——《領域驅動設計模式、原理與實踐》

當你來到一個項目一眼看到這么多基礎設施相關的目錄結構時:

  1. ├── controller 
  2. ├── interceptor 
  3. ├── jms 
  4. ├── rocketmq 
  5. ├── schedule 
  6. └── task 

有一天,我們又加了一個 Kafka,我們又不新加一個文件夾,而這樣的分層設計看上去沒有一點組織。然后呢,我們打開目錄的時候,無法快速定位到我們的代碼。

除了從目錄上 infrastructure 包/層,容納相關的基礎設施代碼。我們還要考慮到分層上的單一職責,因為需要剝離基礎設施與業務代碼的關系。所以,為了實現 Clean Architecture 的大業,你還需要一層抽象接口,比如你要訪問存儲業務相關的數據。那么抽象在你的 domain 中,具體的 RepositoryImpl 實現是在你的基礎設施。

離心分離模型

 

在一個系統中,你會存在這么一些不同的 model:

(PS:部分描述可能不準確,歡迎指正)

  • 與數據庫表結構對應的 DO( Data Object)/ PO(Persistant Object)。
  • 查詢數據的 Query、Request。
  • 對外傳輸的對象:DTO( Data Transfer Object)。
  • 業務層之間的數據對象:VO(Value Object) / BO(Business Object)。
  • 訪問數據庫的:DAO (Data Access Object數據訪問對象)。
  • 以及我們想要的 DDD 中的實體 Entity
  • 還有其它的 POJO( Plain Ordinary Java Object)

但是它們都是 model,所以它們都被扔到 model 中……,又或者是 bean 中……。導致,你有了一個巨大比的 model 層。

所以,在 DDD 又或者是 Clean Architecture,我們重新命名了不同的模式:

  • 使用 Command / Request 作為輸入參數。其中的 Command 模式在完成后需要發出對應的 Event。
  • 使用 Response / DTO / Representation 作為返回結果。
  • 對 Entity 大家保持了一致的意見
  • 還有 PO / DO 作為作為數據庫的存儲模型
  • DAO 作為數據庫的訪問模型
  • ……

不過,其實你只要不再讓使用 model 和 bean,相似會有更多地收獲。

以領域為核心,豐富行為

 

當完成了大坨的移動文件夾操作之后,我們來到了最麻煩和復雜的一部分。

我們需要對領域模型進行重新建模,重新規劃 model 和 service,讓 model 變成了富血模型。也許,你需要一場 Event Storming,才能完成真正意義的事件風暴建模。不過,步驟上也不會有太多的差異。

  1. 重新劃分包。即在保持業務不中斷的情況下重構,以讓新的代碼運行在新的架構上。
  2. 分析抽象領域模型
  3. 編寫 API 測試,保證現有的功能
  4. 編寫抽象接口,進行依賴反轉
  5. 拆分 service 層,重構代碼。將行為綁定于是領域對象上。

其它的情況,還要進行 case by case 的分析。

剩下的呢?

共享的業務邏輯,可以采用 sharedkernel,或者其它模式來處理。

待繼續補充。

代碼共用分層:功能內聚

 

創建通用的共享組件導致了一系列問題,比如耦合、協調難度和復雜度增加。

當我看到一個個巨大的 common 包時,我開始痛恨 common、 base、 util 這些該死的包,還有它們目錄下統一管理的 bean。我們真的已經把它們用爛了,所以你應該重新審視一下你的項目代碼。

所以,從這種意義上來說:復用與低耦合,本身存在一定的互斥關系。

base 下的 base

過去,我曾經重構過一個 base 項目的代碼,正是這次重構讓我意識到 base 并不是一個好東西。如果在項目中已經抽取出了一個 base 模塊,那么這個模塊下是不應該存在 base 這樣的業務邏輯。而且,base 這個東西導致了一個問題是,只要是共用的東西就會不加思索的扔到 base 中。

你會有一個 base 的包,放著各種抽象接口,但是你需要一個更好的名字,比如 concepts,比如 support。

總之,你不應該存在 base 模塊,讓開發人員思考一下哪去放新的類。

無比臃腫的 bean 和 model

“這本身是怪不得程序員的,要怪就怪該死的 Java 語言。”

轉而,我開始考慮一個問題,當個包(文件夾)下的文件數是否不應該超過一定的數量?

如果一個包下的類數,超過一定的范圍,那么我們應該考慮是否存在職責相似的類。

這部分可以參考上一部分的離心分離模型。

什么不是 common

common 這個名字真的很爛,比 base 和 model 更爛。

一旦你從項目中拆出了一個 common 模塊,那只會有一個結果,你將得到一個 5G 時代的 jar 包。甚至于,你看到有一塊代碼在 IDE 中是灰色的、未使用的,你也不敢輕易去刪除這些代碼。直到有一天,這個 common 包構建出來的大小有 10M、20M,而你只需要引用一個 AESUtil 的時候,你才發現了問題:原本幾十 K 的 hello, world,現在變成了幾十 M。

不要事先創建 common 模塊,你可能不會有這個模塊。

任何的水平分層拆分應用,在項目復雜化的今天都是不靠譜的。

誰用誰管理,而不是覺得是 common 就扔 common 模塊。

它真是個 util 嗎?

 

哦,不,它是個惡魔,因為它是 util。

你會往 xxUtil 不加思索地扔入邏輯,正如你會往 common/bean 中扔入所有的 model,直次有一天,你擁有一個巨大無比的 base、common 代碼。

大多數情況下,所有和業務相關的 Util 都存在一定的問題,如 CaptchaUtil,它要么應該劃到自己的上下文中去,要么扔到諸如于 domain/shared 等共享上下文,而不是和其它 util 放到一起。

而諸如 FileUtil、DateUtil、RedisUtil、JdbcUtil 這些都可以說是基礎設施相關的部分,它們可以劃到 infrastructure/file 又或者是 infrastructure/date 目錄下,而不是統一的管理這些 util。

如 StackOverflow 的相關問題所列,我們還有諸如 Coordinator、Builder、Writer、Reader、Handler、Container、Protocol、Target、Converter、Controller、View、Factory、Entity、Bucket 等名稱。

試著干掉 Util,你將收獲更多的類,笑~。

需要個例子?

看看 Spring Framework 的源碼的分層結構,如 Spring Orm:

  1. └── orm 
  2.  ├── ObjectOptimisticLockingFailureException.java 
  3.  ├── ObjectRetrievalFailureException.java 
  4.  ├── hibernate5a/ 
  5.  ├── jpa/ 
  6.  └── package-info.java 

又或者是 spring-context 下的目錄分層結構:

  1. └── springframework 
  2.  ├── cache 
  3.  │   ├── annotation 
  4.  │   ├── concurrent 
  5.  │   ├── config 
  6.  │   ├── interceptor 
  7.  │   └── support 
  8.  ├── context 
  9.  │   ├── annotation 
  10.  │   ├── config 
  11.  │   ├── event 
  12.  │   ├── expression 
  13.  │   ├── i18n 
  14.  │   ├── index 
  15.  │   ├── support 
  16.  │   └── weaving 

它們都在自己的限界上下文內,維護自己的 annotaion、bean、support、i18n 等等的包。

分層架構重構

 

所以,我們可以嘗試這么去做架構重構

  1. 分析、診斷現有項目結構
  2. 劃分新的分層架構
  3. 功能測試
  4. 使用抽象解耦依賴
  5. 進行細粒度的代碼重構
  6. 重新劃分領域服務

還有嗎?

  1. 不要預先設計,而是定義原則與規范。
  2. 以簡單的設計開始,在生命周期中演進架構。
  3. 以多個 common 包,替代統一的 common 包
  4. TBC。

結論

 

那么,我們怎么才能做好分層架構呢?

by experience。

哦,不對,DDD 大法好。

責任編輯:武曉燕 來源: Phodal phodal
相關推薦

2012-05-11 09:45:07

海量數據

2022-02-22 19:26:58

Wi-Fi 6EWi-Fi 7Wi-Fi 6

2009-07-27 10:11:08

富士康孫丹勇

2019-05-23 11:23:50

2013-07-15 09:57:24

微軟SaaSTurner

2023-03-09 08:13:34

2022-05-17 14:17:50

物理安全網絡攻擊網絡安全

2020-11-17 09:15:21

ColabJupyterPython

2021-06-17 07:47:03

軟件架構分層

2019-12-18 15:05:17

運營商5G物聯網

2023-01-05 08:12:11

分層應用代碼

2015-03-12 11:04:39

App StoreDNS宕機

2015-03-12 09:57:44

App StoreDNS宕機

2009-06-02 09:48:36

分層架構PetShop.NET

2023-08-02 08:51:46

服務架構分層架構

2025-11-14 09:13:52

2023-04-07 14:04:51

AI

2024-03-29 12:50:00

項目分層模型

2023-06-16 13:34:00

軟件架構模式

2020-08-12 09:44:10

AI 數據人工智能
點贊
收藏

51CTO技術棧公眾號

看片网站欧美日韩| 一本久道久久综合| 国产69精品久久久久777| 在线观看麻豆| 午夜精品久久久久久久男人的天堂| 久久99久久精品| 亚洲综合图区| 精品视频一区在线| 欧美又粗又大又爽| 国产大片一区| 在线看国产视频| 国产精品一区二区三区毛片淫片| 中文字幕二三区不卡| 亚洲久草在线| 精品无码国模私拍视频| 一本大道久久加勒比香蕉| 久草在线在线精品观看| 性网站在线观看| 日韩欧美一区二区三区四区| 欧美一区二区播放| 日日夜夜免费精品| av电影在线地址| 中文字幕一区二区三区精彩视频| 亚洲第一色在线| 激情六月婷婷久久| 日本不卡网站| xxxxxx在线观看| 中文在线不卡视频| 99久久精品情趣| 中文字幕视频精品一区二区三区| 免费高清在线观看免费| 欧美高清激情视频| 国产精品理论片| 免费看成人吃奶视频在线| 无夜福利视频观看| 国产在线观看不卡| 色婷婷av一区二区| 西西人体一区二区| 乱人伦视频在线| 妞干网在线观看视频| 欧美日韩福利电影| 一级特黄大欧美久久久| 在线观看国产精品入口| 黄色免费在线网站| www婷婷av久久久影片| 久久久精品在线观看| 亚洲国产精品高清| 精品久久久久久久| 天堂资源在线中文| 欧美另类videos| 久久噜噜噜精品国产亚洲综合| 一区二区三区四区中文字幕| 欧美日韩视频一区二区三区| 91黄页在线观看| 一本久道综合色婷婷五月| 国产成人综合精品在线| 精品视频一区 二区 三区| 麻豆精品久久精品色综合| 成人亚洲精品| 夜色资源站国产www在线视频| 蜜桃导航-精品导航| 国产一区二区激情| 亚洲日本丝袜连裤袜办公室| 欧美精品国产一区二区| 亚洲黄色免费看| 成人黄网大全在线观看| 99热最新在线| 亚洲色图校园春色| 亚洲男人都懂的| 99riav国产精品| 日本在线一区二区| 亚洲综合色视频在线观看| 一区不卡字幕| 欧美影院久久久| 日韩亚洲欧美高清| 国产欧美日韩亚州综合| 亚洲黄色影院| 日韩免费一级| se在线电影| 免费 成 人 黄 色| 亚洲一区久久久| 中文字幕日韩专区| 欧美视频第一页| www.亚洲色图.com| 国产精品v亚洲精品v日韩精品 | 97久久超碰国产精品| 91影院成人| 在线免费看h| 美国成人av| 亚洲高潮无码久久| 91精品久久久久久综合乱菊| 日韩精品在线播放| 亚洲成人精品影院| 国产91精品在线观看| 亚洲老妇激情| 国产精品视频一区视频二区 | 亚洲欧洲一二区| 免费观看成人高潮| 97操碰视频| 一区二区三区四区久久| 国产日产久久高清欧美一区| 最近2019中文字幕mv免费看| 欧美午夜电影一区| 国产精品美女久久久久久2018| 日韩经典一区二区| 99国产精品一区二区| 精品中文在线| gratisvideos另类灌满| 美女网站在线观看| 妞干网在线免费视频| 日本在线成人一区二区| 成人激情综合网| 欧美精品久久久久久久久| 亚洲国产中文字幕久久网| 一本色道a无线码一区v| 国产精品久久精品日日| 成人午夜电影网站| 日韩高清不卡在线| 欧美日韩网站| 国产精品一区二区av交换| 丰满少妇一区| 日本色护士高潮视频在线观看| 亚洲精品视频在线免费| 日韩大片一区二区| 国产青草视频在线观看| 日韩在线电影一区| 高清国产在线一区| 国产精品69av| 国内精品久久久久久久| 中文字幕av一区二区| 亚洲国产成人久久| 欧美日精品一区视频| 亚洲国产精品欧美一二99| 欧美经典一区二区| kk眼镜猥琐国模调教系列一区二区| 欧美a级一区二区| 亚洲一区日韩| 欧美精品观看| 久久久久av| 久久精品国产99久久| 亚洲三级网页| 欧美变态网站| 激情小说亚洲图片| 91久久精品无嫩草影院| 韩国一区二区三区视频| 日本黄色成人| 成人福利一区二区| 日韩精品麻豆| 国产精品亚洲d| 91另类视频| 国产精品99精品一区二区三区∴| 亚洲一二三四| 韩国主播福利视频一区二区三区| 国产高清中文字幕在线| 不卡一本毛片| a国产在线视频| www成人免费观看| 欧美激情20| 成人在线视频播放| 免费污视频在线一区| 日韩漫画puputoon| 亚洲精品69| 伊人久久影院| 婷婷精品在线观看| 国产精品一区二区av日韩在线| 四虎5151久久欧美毛片| 欧美精品第一区| 久久国产电影| 欧美日韩在线大尺度| 夜夜嗨一区二区| 日本亚洲最大的色成网站www| 久久亚洲风情| 久久精品99国产国产精| 国产麻豆日韩欧美久久| 岛国一区二区三区| 久久久久亚洲综合| 亚洲天堂成人在线观看| 亚洲图片欧美综合| 91黄色小视频| 欧美mv日韩mv国产网站app| 亚洲精品xxx| www.日韩.com| 午夜精品国产精品大乳美女| 日韩av电影院| av一区二区三区在线观看| 欧美日韩综合网| 免费人成在线观看视频播放| 日本男人操女人| 麻豆传媒在线播放| 日本在线观看网站| 日本不卡网站| 国产毛片精品| 中国精品18videos性欧美| 一本久道综合久久精品| 黄色资源网久久资源365| 91美女片黄在线观看| 亚洲一区二区三区免费视频| 91精品国产综合久久久久久漫画| 亚洲欧洲在线播放| 亚州av一区二区|