日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
為什么從MVC到DDD,架構(gòu)的本質(zhì)是什么?

今天要分享的是 MVC 和 DDD 的架構(gòu)本質(zhì),通過由淺入深的介紹講解和視頻帶著手把手操作創(chuàng)建工程架構(gòu)。讓無論是學(xué)習(xí) MVC 的小白碼農(nóng)還是希望了解更多關(guān)于 DDD 內(nèi)容的老白碼農(nóng),都可以學(xué)習(xí)到一點自己需要的內(nèi)容。

創(chuàng)新互聯(lián)專注于集賢網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供集賢營銷型網(wǎng)站建設(shè),集賢網(wǎng)站制作、集賢網(wǎng)頁設(shè)計、集賢網(wǎng)站官網(wǎng)定制、小程序設(shè)計服務(wù),打造集賢網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供集賢網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

一、MVC 架構(gòu)

如果我們嘗試把編程的復(fù)雜架構(gòu)縮小到最容易理解的程度,那么編程開發(fā)其實只做3件事:”定義屬性、創(chuàng)建方法、調(diào)用展示“。但因為同類所需的內(nèi)容較多,如一系列的屬性,一堆的方法實現(xiàn),一組的接口封裝,那么就需要合理的把這些內(nèi)容分配到不同的層次中去實現(xiàn),因此有了分層架構(gòu)的設(shè)計。

那么本文小傅哥會向大家介紹一套MVC架構(gòu)的分層設(shè)計以及如何創(chuàng)建使用,并提供相應(yīng)的簡單的案例。你可以復(fù)制這套架構(gòu)在自己的場景中使用,也更能方便編程的小白可以更快的上手開發(fā)。

注意:此套MVC架構(gòu)模型適合提供HTTP服務(wù)的工程架構(gòu),適合簡單的小場景開發(fā)使用。特點;輕便、簡單、學(xué)習(xí)成本低。

1. 編程三步

如果說你是一個特別小的玩具項目,你甚至可以把編程的3步寫到一個類里。但因為你做的是正經(jīng)項目,你的各種類;對象類、庫表類、方法類,就會成群結(jié)隊的來。如果你想把這些成群結(jié)隊的類的內(nèi)容,都寫到一個類里去,那么就是幾萬行的代碼了?!?當(dāng)然你也可以吹牛逼,你一個人做過一個項目,這項目大到啥程度呢。就是有一個類里有上萬行代碼。

圖片

所以,為了不至于讓一個類撐到爆,需要把黃色的對象、綠色的方法、紅色的接口,都分配到不同的包結(jié)構(gòu)下。這就是你編碼人生中所接觸到的第一個解耦操作。

2. 分層框架

MVC 是一種非常常見且常用的分層架構(gòu),主要包括;M - mode 對象層,封裝到 domain 里。V - view 展示層,但因為目前都是前后端分離的項目,幾乎不會在后端項目里寫 JSP 文件了。C - Controller 控制層,對外提供接口實現(xiàn)類。DAO 算是單獨拿出來用戶處理數(shù)據(jù)庫操作的層。

圖片

  • 如圖,在 MVC 的分層架構(gòu)下。我們編程3步的所需各類對象、方法、接口,都分配到 MVC 的各個層次中去。
  • 因為這樣分層以后,就可以很清晰明了的知道各個層都在做什么內(nèi)容,也更加方便后續(xù)的維護(hù)和迭代。
  • 對于一個真正的項目來說,是沒有一錘子買賣的,最開始的開發(fā)遠(yuǎn)不是成本所在。最大的開發(fā)成本是后期的維護(hù)和迭代。而架構(gòu)設(shè)計的意義更多的就是在解決系統(tǒng)的反復(fù)的維護(hù)和迭代時,如何降低成本,這也是架構(gòu)分層的意義所在。

3. 調(diào)用流程

接下來我們再看下一套 MVC 架構(gòu)中各個模塊在調(diào)用時的串聯(lián)關(guān)系;

圖片

  • 以用戶發(fā)起 HTTP 請求開始,Controller 在接收到請求后,調(diào)用由 Spring 注入到類里的 Service 方法,進(jìn)入 Service 方法后有些邏輯會走數(shù)據(jù)庫,有些邏輯是直接內(nèi)部自己處理后就直接返回給 Controller 了。最后由 Controller 封裝結(jié)果返回給 HTTP 響應(yīng)。
  • 同時我們也可以看到各個對象在這些請求間的一個作用,如;請求對象、庫表對象、返回對象。

4. 架構(gòu)源碼

4.1 環(huán)境

  • JDK 1.8
  • Maven 3.8.6 - 下載安裝maven后,本地記得配置阿里云鏡像,方便快速拉取jar包。源碼中 docs/maven/settings.xml 有阿里云鏡像地址。
  • SpringBoot 2.7.2
  • MySQL 5.7 - 如果你使用 8.0 記得更改 pom.xml 中的 mysql 引用

4.2 架構(gòu)

  • 源碼:https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-mvc
  • 樹形:安裝 brew install tree IntelliJ IDEA Terminal 使用 tree
.
├── docs
│   └── mvc.drawio - 架構(gòu)文檔
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── cn
│   │   │       └── bugstack
│   │   │           └── xfg
│   │   │               └── frame
│   │   │                   ├── Application.java
│   │   │                   ├── common
│   │   │                   │   ├── Constants.java
│   │   │                   │   └── Result.java
│   │   │                   ├── controller
│   │   │                   │   └── UserController.java
│   │   │                   ├── dao
│   │   │                   │   └── IUserDao.java
│   │   │                   ├── domain
│   │   │                   │   ├── po
│   │   │                   │   │   └── User.java
│   │   │                   │   ├── req
│   │   │                   │   │   └── UserReq.java
│   │   │                   │   ├── res
│   │   │                   │   │   └── UserRes.java
│   │   │                   │   └── vo
│   │   │                   │       └── UserInfo.java
│   │   │                   └── service
│   │   │                       ├── IUserService.java
│   │   │                       └── impl
│   │   │                           └── UserServiceImpl.java
│   │   └── resources
│   │       ├── application.yml
│   │       └── mybatis
│   │           ├── config
│   │           │   └── mybatis-config.xml
│   │           └── mapper
│   │               └── User_Mapper.xml
│   └── test
│       └── java
│           └── cn
│               └── bugstack
│                   └── xfg
│                       └── frame
│                           └── test
│                               └── ApiTest.java
└── road-map.sql

以上是整個工程架構(gòu)的 tree 樹形圖。整個工程由 SpringBoot 驅(qū)動。

  • Application.java 是啟動程序的 SpringBoot 應(yīng)用
  • common 是額外添加的一個層,用于定義通用的類
  • controller 控制層,提供接口實現(xiàn)。
  • dao 數(shù)據(jù)庫操作層
  • domain 對象定義層
  • service 服務(wù)實現(xiàn)層

5. 測試驗證

  • 首先;整個工程由 SpringBoot 驅(qū)動,提供了 road-map.sql 測試 SQL 庫表語句。你可以在自己的本地mysql上進(jìn)行執(zhí)行。它會創(chuàng)建庫表。
  • 之后;在 application.yml 配置數(shù)據(jù)庫鏈接信息。
  • 之后就可以打開 ApiTest 進(jìn)行測試了。你可以點擊 Application 類的綠色箭頭啟動工程,使用 UserController 類提供接口的方式調(diào)用程序;http://localhost:8089/queryUserInfo

圖片

- 如果你正常獲取了這樣的結(jié)果信息,那么說明你已經(jīng)啟動成功。接下來就可以對照著MVC的結(jié)構(gòu)進(jìn)行學(xué)習(xí),以及使用這樣的工程結(jié)構(gòu)開發(fā)自己的項目。

二、DDD 架構(gòu)

從最早接觸 DDD 架構(gòu),到后來用 DDD 架構(gòu)不斷的承接項目開發(fā),一次次在項目開發(fā)中的經(jīng)驗積累。對 DDD 有了不少的理解。DDD 是一種思想,落地的形態(tài)和結(jié)構(gòu)會有不同的方式,甚至在編碼上也會有風(fēng)格的差異。但終期目標(biāo)就一個;”提供代碼的可維護(hù)性,降低迭代開發(fā)成本?!耙彩强低伤觯骸比魏谓M織在設(shè)計一套系統(tǒng)時,所交付的設(shè)計方案在結(jié)構(gòu)上都與該組織的溝通結(jié)構(gòu)保持一致?!?/p>

但 DDD 與 MVC 相比的概率較多,貿(mào)然用理論驅(qū)動代碼開發(fā),會讓整個工程變得非常混亂,甚至可能雖然是用的 DDD 但最后寫出來了一片四不像的 MVC 代碼。所以對于程序員來說,先能上手一個工程,在從工程了解理論會更加容易。為此小傅哥想以此文,通過實戰(zhàn)編碼的方式向大家分享 DDD 架構(gòu),并能讓大家上手的 DDD 架構(gòu)。

1. 問題碰撞

你用 MVC 寫代碼,遇到過最大的問題是什么?????

簡單、容易、好理解,是 MVC 架構(gòu)的特點,但也正因為簡單的分層邏輯,在適配較復(fù)雜的場景并且需要長周期的維護(hù)時,代碼的迭代成本就會越來越高。如圖;

圖片

  • 如果你接觸過較大型且已經(jīng)長期維護(hù)項目的 MVC 架構(gòu),你就會發(fā)現(xiàn)這里的 DAO、PO、VO 對象,在 Service 層相互調(diào)用。那么長期開發(fā)后,就導(dǎo)致了各個 PO 里的屬性字段數(shù)量都被撐的特別大。這樣的開發(fā)方式,將”狀態(tài)”、“行為“分離到不同的對象中,代碼的意圖漸漸模糊,膨脹、臃腫和不穩(wěn)定的架構(gòu),讓迭代成本增加。
  • 而 DDD 架構(gòu)首先以解決此類問題為主,將各個屬于自己領(lǐng)域范圍內(nèi)的行為和邏輯封裝到自己的領(lǐng)域包下處理。這也是 DDD 架構(gòu)設(shè)計的精髓之一。它希望在分治層面合理切割問題空間為更小規(guī)模的若干子問題,而問題越小就容易被理解和處理,做到高內(nèi)聚低耦合。這也是康威定律所提到的,解決復(fù)雜場景的設(shè)計主要分為:分治、抽象和知識。

2. 簡化理解

在給大家講解 MVC 架構(gòu)的時候,小傅哥提到了一個簡單的開發(fā)模型。開發(fā)代碼可以理解為:“定義屬性 -> 創(chuàng)建方法 -> 調(diào)用展示” 但這個模型結(jié)構(gòu)過于簡單,不太適合運用了各類分布式技術(shù)棧以及更多邏輯的 DDD 架構(gòu)。所以在 DDD 這里,我們把開發(fā)代碼可以抽象為:“觸發(fā) -> 函數(shù) -> 連接” 如圖;

圖片

  • DDD 架構(gòu)常用于微服務(wù)場景,因此也一個系統(tǒng)的調(diào)用方式就不只是 HTTP 還包括;RPC 遠(yuǎn)程、MQ 消息、TASK 任務(wù),因此這些種方式都可以理解為觸發(fā)。
  • 通過觸發(fā)調(diào)用函數(shù)方法,我們這里可以把各個服務(wù)都當(dāng)成一個函數(shù)方法來看。而函數(shù)方法通過連接,調(diào)用到其他的接口、數(shù)據(jù)庫、緩存來完成函數(shù)邏輯。

接下來,小傅哥在帶著大家把這些所需的模塊,拆分到對應(yīng)的DDD系統(tǒng)架構(gòu)中。

3. 架構(gòu)分層

如下是 DDD 架構(gòu)的一種分層結(jié)構(gòu),也可以有其他種方式,核心的重點在于適合你所在場景的業(yè)務(wù)開發(fā)。以下的分層結(jié)構(gòu),是小傅哥在使用 DDD 架構(gòu)多種的方式開發(fā)代碼后,做了簡化和處理的。右側(cè)的連線是各個模塊的依賴關(guān)系。接下來小傅哥就給大家做一下模塊的介紹。

圖片

  • 接口定義 - xfg-frame-api:因為微服務(wù)中引用的 RPC 需要對外提供接口的描述信息,也就是調(diào)用方在使用的時候,需要引入 Jar 包,讓調(diào)用方好能依賴接口的定義做代理。
  • 應(yīng)用封裝 - xfg-frame-app:這是應(yīng)用啟動和配置的一層,如一些 aop 切面或者 config 配置,以及打包鏡像都是在這一層處理。你可以把它理解為專門為了啟動服務(wù)而存在的。
  • 領(lǐng)域封裝 - xfg-frame-domain:領(lǐng)域模型服務(wù),是一個非常重要的模塊。無論怎么做DDD的分層架構(gòu),domain 都是肯定存在的。在一層中會有一個個細(xì)分的領(lǐng)域服務(wù),在每個服務(wù)包中會有【模型、倉庫、服務(wù)】這樣3部分。
  • 倉儲服務(wù) - xfg-frame-infrastructure:基礎(chǔ)層依賴于 domain 領(lǐng)域?qū)?,因為?domain 層定義了倉儲接口需要在基礎(chǔ)層實現(xiàn)。這是依賴倒置的一種設(shè)計方式。
  • 領(lǐng)域封裝 - xfg-frame-trigger:觸發(fā)器層,一般也被叫做 adapter 適配器層。用于提供接口實現(xiàn)、消息接收、任務(wù)執(zhí)行等。所以對于這樣的操作,小傅哥把它叫做觸發(fā)器層。
  • 類型定義 - xfg-frame-types:通用類型定義層,在我們的系統(tǒng)開發(fā)中,會有很多類型的定義,包括;基本的 Response、Constants 和枚舉。它會被其他的層進(jìn)行引用使用。
  • 領(lǐng)域編排【可選】 - xfg-frame-case:領(lǐng)域編排層,一般對于較大且復(fù)雜的的項目,為了更好的防腐和提供通用的服務(wù),一般會添加 case/application 層,用于對 domain 領(lǐng)域的邏輯進(jìn)行封裝組合處理。

4. 架構(gòu)源碼

4.1 環(huán)境

  • JDK 1.8
  • Maven 3.8.6
  • SpringBoot 2.7.2
  • MySQL 5.7 - 如果你使用 8.0 記得更改 pom.xml 中的 mysql 引用

4.2 架構(gòu)

  • 源碼:https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd
  • 樹形:安裝 brew install tree IntelliJ IDEA Terminal 使用 tree
.
├── README.md
├── docs
│   ├── dev-ops
│   │   ├── environment
│   │   │   └── environment-docker-compose.yml
│   │   ├── siege.sh
│   │   └── skywalking
│   │       └── skywalking-docker-compose.yml
│   ├── doc.md
│   ├── sql
│   │   └── road-map.sql
│   └── xfg-frame-ddd.drawio
├── pom.xml
├── xfg-frame-api
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── api
│   │                               ├── IAccountService.java
│   │                               ├── IRuleService.java
│   │                               ├── model
│   │                               │   ├── request
│   │                               │   │   └── DecisionMatterRequest.java
│   │                               │   └── response
│   │                               │       └── DecisionMatterResponse.java
│   │                               └── package-info.java
│   └── xfg-frame-api.iml
├── xfg-frame-app
│   ├── Dockerfile
│   ├── build.sh
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── bin
│   │   │   │   ├── start.sh
│   │   │   │   └── stop.sh
│   │   │   ├── java
│   │   │   │   └── cn
│   │   │   │       └── bugstack
│   │   │   │           └── xfg
│   │   │   │               └── frame
│   │   │   │                   ├── Application.java
│   │   │   │                   ├── aop
│   │   │   │                   │   ├── RateLimiterAop.java
│   │   │   │                   │   └── package-info.java
│   │   │   │                   └── config
│   │   │   │                       ├── RateLimiterAopConfig.java
│   │   │   │                       ├── RateLimiterAopConfigProperties.java
│   │   │   │                       ├── ThreadPoolConfig.java
│   │   │   │                       ├── ThreadPoolConfigProperties.java
│   │   │   │                       └── package-info.java
│   │   │   └── resources
│   │   │       ├── application-dev.yml
│   │   │       ├── application-prod.yml
│   │   │       ├── application-test.yml
│   │   │       ├── application.yml
│   │   │       ├── logback-spring.xml
│   │   │       └── mybatis
│   │   │           ├── config
│   │   │           │   └── mybatis-config.xml
│   │   │           └── mapper
│   │   │               ├── RuleTreeNodeLine_Mapper.xml
│   │   │               ├── RuleTreeNode_Mapper.xml
│   │   │               └── RuleTree_Mapper.xml
│   │   └── test
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── test
│   │                               └── ApiTest.java
│   └── xfg-frame-app.iml
├── xfg-frame-ddd.iml
├── xfg-frame-domain
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── domain
│   │                               ├── order
│   │                               │   ├── model
│   │                               │   │   ├── aggregates
│   │                               │   │   │   └── OrderAggregate.java
│   │                               │   │   ├── entity
│   │                               │   │   │   ├── OrderItemEntity.java
│   │                               │   │   │   └── ProductEntity.java
│   │                               │   │   ├── package-info.java
│   │                               │   │   └── valobj
│   │                               │   │       ├── OrderIdVO.java
│   │                               │   │       ├── ProductDescriptionVO.java
│   │                               │   │       └── ProductNameVO.java
│   │                               │   ├── repository
│   │                               │   │   ├── IOrderRepository.java
│   │                               │   │   └── package-info.java
│   │                               │   └── service
│   │                               │       ├── OrderService.java
│   │                               │       └── package-info.java
│   │                               ├── rule
│   │                               │   ├── model
│   │                               │   │   ├── aggregates
│   │                               │   │   │   └── TreeRuleAggregate.java
│   │                               │   │   ├── entity
│   │                               │   │   │   ├── DecisionMatterEntity.java
│   │                               │   │   │   └── EngineResultEntity.java
│   │                               │   │   ├── package-info.java
│   │                               │   │   └── valobj
│   │                               │   │       ├── TreeNodeLineVO.java
│   │                               │   │       ├── TreeNodeVO.java
│   │                               │   │       └── TreeRootVO.java
│   │                               │   ├── repository
│   │                               │   │   ├── IRuleRepository.java
│   │                               │   │   └── package-info.java
│   │                               │   └── service
│   │                               │       ├── engine
│   │                               │       │   ├── EngineBase.java
│   │                               │       │   ├── EngineConfig.java
│   │                               │       │   ├── EngineFilter.java
│   │                               │       │   └── impl
│   │                               │       │       └── RuleEngineHandle.java
│   │                               │       ├── logic
│   │                               │       │   ├── BaseLogic.java
│   │                               │       │   ├── LogicFilter.java
│   │                               │       │   └── impl
│   │                               │       │       ├── UserAgeFilter.java
│   │                               │       │       └── UserGenderFilter.java
│   │                               │       └── package-info.java
│   │                               └── user
│   │                                   ├── model
│   │                                   │   └── valobj
│   │                                   │       └── UserVO.java
│   │                                   ├── repository
│   │                                   │   └── IUserRepository.java
│   │                                   └── service
│   │                                       ├── UserService.java
│   │                                       └── impl
│   │                                           └── UserServiceImpl.java
│   └── xfg-frame-domain.iml
├── xfg-frame-infrastructure
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── infrastructure
│   │                               ├── dao
│   │                               │   ├── IUserDao.java
│   │                               │   ├── RuleTreeDao.java
│   │                               │   ├── RuleTreeNodeDao.java
│   │                               │   └── RuleTreeNodeLineDao.java
│   │                               ├── package-info.java
│   │                               ├── po
│   │                               │   ├── RuleTreeNodeLineVO.java
│   │                               │   ├── RuleTreeNodeVO.java
│   │                               │   ├── RuleTreeVO.java
│   │                               │   └── UserPO.java
│   │                               └── repository
│   │                                   ├── RuleRepository.java
│   │                                   └── UserRepository.java
│   └── xfg-frame-infrastructure.iml
├── xfg-frame-trigger
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── trigger
│   │                               ├── http
│   │                               │   ├── Controller.java
│   │                               │   └── package-info.java
│   │                               ├── mq
│   │                               │   └── package-info.java
│   │                               ├── rpc
│   │                               │   ├── AccountService.java
│   │                               │   ├── RuleService.java
│   │                               │   └── package-info.java
│   │                               └── task
│   │                                   └── package-info.java
│   └── xfg-frame-trigger.iml
└── xfg-frame-types
    ├── pom.xml
    ├── src
    │   └── main
    │       └── java
    │           └── cn
    │               └── bugstack
    │                   └── xfg
    │                       └── frame
    │                           └── types
    │                               ├── Constants.java
    │                               ├── Response.java
    │                               └── package-info.java
    └── xfg-frame-types.iml

以上是整個工程架構(gòu)的 tree 樹形圖。整個工程由  xfg-frame-app 模的 SpringBoot 驅(qū)動。這里小傅哥在 domain 領(lǐng)域模型下提供了 order、rule、user 三個領(lǐng)域模塊。并在每個模塊下提供了對應(yīng)的測試內(nèi)容。這塊是整個模型的重點,其他模塊都可以通過測試看到這里的調(diào)用過程。

4.3 領(lǐng)域

一個領(lǐng)域模型中包含3個部分;model、repository、service 三部分;

  • model 對象的定義
  • repository 倉儲的定義
  • service 服務(wù)實現(xiàn)

以上3個模塊,一般也是大家在使用 DDD 時候最不容易理解的分層。比如 model 里還分為;valobj - 值對象、entity 實體對象、aggregates 聚合對象;

  • 值對象:表示沒有唯一標(biāo)識的業(yè)務(wù)實體,例如商品的名稱、描述、價格等。
  • 實體對象:表示具有唯一標(biāo)識的業(yè)務(wù)實體,例如訂單、商品、用戶等;
  • 聚合對象:是一組相關(guān)的實體對象的根,用于保證實體對象之間的一致性和完整性;

關(guān)于model中各個對象的拆分,尤其是聚合的定義,會牽引著整個模型的設(shè)計。當(dāng)然你可以在初期使用 DDD 的時候不用過分在意領(lǐng)域模型的設(shè)計,可以把整個 domain 下的一個個包當(dāng)做充血模型結(jié)構(gòu),這樣編寫出來的代碼也是非常適合維護(hù)的。

4.4 環(huán)境(開發(fā)/測試/上線)

源碼:xfg-frame-ddd/pom.xml


    dev
    
        true
    
    
        dev
    


    test
    
        test
    


    prod
    
        prod
    
  • 定義環(huán)境;開發(fā)、測試、上線。

源碼:xfg-frame-app/application.yml

spring:
  config:
    name: xfg-frame
  profiles:
    active: dev # dev、test、prod
  • 除了 pom 的配置,還需要在 application.yml 中指定環(huán)境。這樣就可以對應(yīng)的加載到;application-dev.yml、application-prod.yml、application-test.yml 這樣就可以很方便的加載對應(yīng)的配置信息了。尤其是各個場景中切換會更加方便。

4.5 切面

一個工程開發(fā)中,有時候可能會有很多的統(tǒng)一切面和啟動配置的處理,這些內(nèi)容都可以在 xfg-frame-app 完成。

圖片

源碼:cn.bugstack.xfg.frame.aop.RateLimiterAop

@Slf4j
@Aspect
public class RateLimiterAop {

    private final long timeout;
    private final double permitsPerSecond;
    private final RateLimiter limiter;

    public RateLimiterAop(double permitsPerSecond, long timeout) {
        this.permitsPerSecond = permitsPerSecond;
        this.timeout = timeout;
        this.limiter = RateLimiter.create(permitsPerSecond);
    }

    @Pointcut("execution(* cn.bugstack.xfg.frame.trigger..*.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()", argNames = "jp")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        boolean tryAcquire = limiter.tryAcquire(timeout, TimeUnit.MILLISECONDS);
        if (!tryAcquire) {
            Method method = getMethod(jp);
            log.warn("方法 {}.{} 請求已被限流,超過限流配置[{}/秒]", method.getDeclaringClass().getCanonicalName(), method.getName(), permitsPerSecond);
            return Response.builder()
                    .code(Constants.ResponseCode.RATE_LIMITER.getCode())
                    .info(Constants.ResponseCode.RATE_LIMITER.getInfo())
                    .build();
        }
        return jp.proceed();
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}

使用

# 限流配置
rate-limiter:
  permits-per-second: 1
  timeout: 5
  • 這樣你所有的通用配置,又和業(yè)務(wù)沒有太大的關(guān)系的,就可以直接寫到這里了。—— 具體可以參考代碼。

5. 測試驗證

  • 首先;整個工程由 SpringBoot 驅(qū)動,提供了 road-map.sql 測試 SQL 庫表語句。你可以在自己的本地mysql上進(jìn)行執(zhí)行。它會創(chuàng)建庫表。
  • 之后;在 application.yml 配置數(shù)據(jù)庫鏈接信息。
  • 之后就可以打開 ApiTest 進(jìn)行測試了。你可以點擊 Application 類的綠色箭頭啟動工程,使用觸發(fā)器里的接口調(diào)用測試,或者單元測試RPC接口,小傅哥也提供了泛化調(diào)用的方式。

圖片

  • 如果你正常獲取了這樣的結(jié)果信息,那么說明你已經(jīng)啟動成功。接下來就可以對照著DDD的結(jié)構(gòu)進(jìn)行學(xué)習(xí),以及使用這樣的工程結(jié)構(gòu)開發(fā)自己的項目。

三、實戰(zhàn) - DDD 項目

紙上得來終覺淺,碼農(nóng)學(xué)習(xí)要實戰(zhàn)!

無論是 MVC 還是各類 DDD 所呈現(xiàn)的架構(gòu),還是需要看到實際的代碼,以及參與實戰(zhàn)開發(fā)才能更好的吸收。否則都是理論仍舊難以讓人下手。

所以小傅哥為大家準(zhǔn)備了一些學(xué)習(xí)項目,這些項目都是非常具有架構(gòu)思維以及設(shè)計模式的應(yīng)用級實戰(zhàn)項目架構(gòu)設(shè)計和落地。對于一些小白來說,如果能早早的接觸到這樣的項目,就相當(dāng)于是提前進(jìn)入企業(yè)實習(xí)了??梢詷O大的提到編程思維以及開發(fā)能力。

這些項目包括:《Lottery 抽獎系統(tǒng) - 基于領(lǐng)域驅(qū)動設(shè)計的四層架構(gòu)實踐》、《API網(wǎng)關(guān):中間件設(shè)計和落地》、《ChatGPT 微服務(wù)應(yīng)用體系搭建》、《IM 仿微信》、《SpringBoot Starter 中間件設(shè)計和落地》等。這里小傅哥只列3張圖,你就知道有多牛皮了!

第1張:Lottery

架構(gòu)

圖片

工程

圖片

第2張:API網(wǎng)關(guān)

架構(gòu)

圖片

工程

圖片

第3張:ChatGPT

圖片


網(wǎng)站欄目:為什么從MVC到DDD,架構(gòu)的本質(zhì)是什么?
本文鏈接:http://m.5511xx.com/article/cdssjih.html