基于Clean Architecture的Go項(xiàng)目架構(gòu)實(shí)踐

經(jīng)過這些年的發(fā)展,Go語言已經(jīng)成為一門被廣泛使用在各個(gè)領(lǐng)域的編程語言。從k8s、docker等基礎(chǔ)組件,到業(yè)務(wù)領(lǐng)域的微服務(wù),都可以用Go構(gòu)建。在構(gòu)建這些Go項(xiàng)目時(shí),采用哪種架構(gòu)模式和代碼布局,是一個(gè)仁者見仁智者見智的事情。有Java Spring經(jīng)驗(yàn)的可能會(huì)采用MVC模式,有Python Flask經(jīng)驗(yàn)的可能會(huì)采用MTV模式。加上Go語言領(lǐng)域并沒有出現(xiàn)主流的企業(yè)級(jí)開發(fā)框架,很多項(xiàng)目甚至沒有明確的架構(gòu)模式。

Clean Architecture

Clean Architecture是Uncle Bob提出的適用于復(fù)雜業(yè)務(wù)系統(tǒng)的架構(gòu)模式,其核心思想是將業(yè)務(wù)復(fù)雜度與技術(shù)復(fù)雜度解藕,相比于MVC、MTV等模式,Clean Architecture除了進(jìn)行分層,還通過約定依賴原則,明確了與外部依賴的交互方式,以及外部依賴與業(yè)務(wù)邏輯的邊界。感興趣的朋友可以直接閱讀作者原文https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html。

由于Clean Architecture具有脫離語言和框架的靈活性,作者在提出時(shí)也沒有規(guī)定實(shí)現(xiàn)細(xì)節(jié),給Clean Architecture的落地帶來了困難,接下來以一個(gè)例子來說明如何在Go項(xiàng)目中應(yīng)用Clean Architecture的思想。

布局

作為一個(gè)Go項(xiàng)目,不管用哪種架構(gòu)模式,建議都建立app和scripts這兩個(gè)路徑。app存放啟動(dòng)Go項(xiàng)目的入口文件,通常是main.go。而scripts可以放一些構(gòu)建和部署時(shí)候用到的腳本。

clean_architecture_demo
├── README.md
├── app
│   └── main.go
├── scripts
│   ├── build.sh
│   └── run.sh
├── go.mod
├── go.sum
└── usecases

接下來是代碼部分,分為entities、usecases、adapters三個(gè)部分。

  • entities:存儲(chǔ)領(lǐng)域?qū)嶓w。用一個(gè)博客系統(tǒng)舉例,領(lǐng)域?qū)嶓w可能有用戶(user)和文章(article)
  • usecases:存儲(chǔ)業(yè)務(wù)邏輯。用博客系統(tǒng)舉例,可能會(huì)有用戶相關(guān)的業(yè)務(wù)邏輯(signup_user、signin_user、add_user、delete_user)和文章相關(guān)的業(yè)務(wù)邏輯(add_article、show_article、delete_article)
  • adapters:存儲(chǔ)適配器邏輯。適配器是連接業(yè)務(wù)邏輯與外部依賴的層,博客以Web形式提供服務(wù),就需要一個(gè)http_adapter來封裝Web服務(wù);同時(shí)保存文章到數(shù)據(jù)庫,需要封裝一個(gè)db_adapter來連接。

下面是項(xiàng)目的布局結(jié)構(gòu)。

clean_architecture_demo
├── README.md
├── adapters
│   ├── api
│   ├── db
│   └── log
├── app
│   └── main.go
├── scripts
│   ├── build.sh
│   └── run.sh
├── entities
│   ├── article.go
│   └── user.go
├── go.mod
├── go.sum
└── usecases

數(shù)據(jù)流向

用一個(gè)查詢文章的請求來描述一下調(diào)用鏈路。

  • 用戶通過HTTP服務(wù)的調(diào)用WebAdapter的ShowArticleHandler方法
  • 由于是文章相關(guān)的邏輯,ShowArticleHandler調(diào)用ArticleUsecase的ShowArticle方法
  • 需要從DB中查詢文章,ArticleUsecase會(huì)調(diào)用DBAdapter的GetArticle方法
  • DBAdapter的GetArticle從MySQL中查詢出文章內(nèi)容返回給ArticleUsecase
  • ArticleUsecase返回給WebAdapter
  • WebAdapter通過HTTP服務(wù)返回給用戶

代碼示例

為了更清晰的說分層和架構(gòu),我在Github上發(fā)布了一個(gè)示例項(xiàng)目,感興趣的朋友可以直接去看源碼:https://github.com/simpleapples/go-clean-architecture

結(jié)論

由于Clean Architecture沒有規(guī)定實(shí)現(xiàn)細(xì)節(jié),所以上述的分層和布局方式只是一種參考,還有眾多的實(shí)踐方式。例如Adapter層可以根據(jù)外部依賴的類型細(xì)分成平行的Presenter+Gateway層,在復(fù)雜項(xiàng)目中,更細(xì)致的分層可以把代碼拆的更細(xì)致,大家可以根據(jù)自己的項(xiàng)目規(guī)模來調(diào)整分層和布局,這里就不做贅述了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容