Golang項(xiàng)目結(jié)構(gòu)設(shè)計(jì)(雙存儲(chǔ)下)
目錄
- 總要
- 結(jié)構(gòu)設(shè)計(jì)
- 控制層和服務(wù)層設(shè)計(jì)
- 服務(wù)層設(shè)計(jì)
- 數(shù)據(jù)訪問(wèn)層設(shè)計(jì)
- 數(shù)據(jù)倉(cāng)庫(kù)層設(shè)計(jì)
前要
我為什么會(huì)寫這篇文章?
避免調(diào)用鏈混亂,代碼可視性差等尷尬問(wèn)題
包結(jié)構(gòu)解釋
|
|--routers 路由層
|--controllers 控制器層,負(fù)責(zé)邏輯判斷和返回結(jié)果
|--service 服務(wù)層,主要是處理控制層傳入的數(shù)據(jù)并進(jìn)行業(yè)務(wù)處理
|--Dao 數(shù)據(jù)訪問(wèn)層 是服務(wù)層獲取數(shù)據(jù)的接口包
|--repository 數(shù)據(jù)倉(cāng)庫(kù)層,把數(shù)據(jù)庫(kù)和redis和其他存儲(chǔ)都放在這個(gè)包下
|--component 組件包,是主要四層的補(bǔ)充,里面一般放不確定那層需要調(diào)用的東西
|--conf 配置包
|--conn 連接包,包括redis菲语、mysql秀姐、id生成器的初始化鏈接
|--constname 常量包,包括默認(rèn)值,業(yè)務(wù)響應(yīng)碼,業(yè)務(wù)響應(yīng)信息,redis的Key
|--filter 過(guò)濾器,負(fù)責(zé)非法請(qǐng)求的攔截、非法詞匯攔截邑雅、接口基本鑒權(quán)嗦玖、身份鑒權(quán)等
|--initialize 初始化包,當(dāng)使用多存儲(chǔ)的時(shí)候患雇,需要先把數(shù)據(jù)庫(kù)的基本數(shù)據(jù)初始化內(nèi)存數(shù)據(jù)庫(kù)中,比如redis
|--middleware 中間件包踏揣,比如jwt等
|--util 工具包,主要是一些小工具的包
組件包和工具包的區(qū)別?
有人可能會(huì)在使用中對(duì)組件包和工具包有困惑庆亡,他們好像有共同之處,其實(shí)不然,對(duì)比而言的話。
不同之處:
組件的體積更為大一些捞稿,組件有可能有自己的結(jié)構(gòu)體和方法,比如你需要定義一個(gè)set數(shù)據(jù)結(jié)構(gòu),除了本身Set數(shù)據(jù)結(jié)構(gòu)以外,還有關(guān)于Set的方法.
工具的體積更為小一些,他可能只是一個(gè)小方法,比較小巧,而且比較零散又谋。
相同之處
他們的共同之處在于:為了讓代碼更好的復(fù)用。
路由層
路由層的作用
供外部訪問(wèn),不多說(shuō)
結(jié)構(gòu)設(shè)計(jì)
路由最好是分組設(shè)計(jì),這樣有比較好的邏輯邊界,并且同一組的路由在一起,看代碼可以一目了然娱局。一般理由的分組按照模型分組即可彰亥。
控制層
控制層的作用:
1、負(fù)責(zé)獲取和反解析前端發(fā)來(lái)的數(shù)據(jù)
2衰齐、做基本的邏輯判斷,傳入的數(shù)據(jù)是否正確和合法
3任斋、將獲取的數(shù)據(jù)傳給服務(wù)層
4、把結(jié)果返回給前端
5耻涛、可能還開始和結(jié)束還包含日志記錄
結(jié)構(gòu)設(shè)計(jì):
在這一層功能相對(duì)來(lái)說(shuō)比較單一,比較簡(jiǎn)單,但是兩點(diǎn)需要注意
1废酷、視圖模型VO(ViewModel)的定義,所以在控制器下應(yīng)該有一個(gè)vo包專門存儲(chǔ)視圖模型
2、控制層的通用或者基礎(chǔ)方法,比如需要有一個(gè)通用的反解析json方法和通用返回結(jié)果方法,這個(gè)可以放在base.go里面
3抹缕、上面說(shuō)到了視圖模型和基礎(chǔ)方法的設(shè)計(jì),具體的控制器和vo澈蟆、base.go平級(jí)即可.
服務(wù)層
服務(wù)層的作用:
1、接收控制層傳入的數(shù)據(jù)
2卓研、對(duì)傳入的數(shù)據(jù)進(jìn)行業(yè)務(wù)判斷,比如能否兌換禮品等
3趴俘、把視圖模型的數(shù)據(jù)賦值給數(shù)據(jù)庫(kù)模型
4睹簇、把業(yè)務(wù)處理結(jié)果返回給控制層
結(jié)構(gòu)設(shè)計(jì):
相對(duì)于其他層來(lái)說(shuō),服務(wù)層的處理邏輯相對(duì)復(fù)雜寥闪,需要注意以下:
1太惠、你可能有通用方法封裝,但是在封裝時(shí),對(duì)于復(fù)雜的操作應(yīng)該單獨(dú)封裝,然后使用組合的方式二次封裝疲憋。
2凿渊、對(duì)于服務(wù)層的返回值。在服務(wù)層應(yīng)該至少有兩個(gè)返回值(res string,err error),為什么要這么做呢,
對(duì)于res,這是業(yè)務(wù)返回結(jié)果,也就是用戶看到的,這樣控制層得到后可以大膽的直接返回給前端柜某。
對(duì)于err,這是服務(wù)為什么得到res這個(gè)結(jié)果的原因,在最后統(tǒng)一記錄日志幫助很大,并且日志代碼并不污染業(yè)務(wù)代碼嗽元。
DAO層
DAO層的作用:
1、從數(shù)據(jù)倉(cāng)庫(kù)中獲取數(shù)據(jù)庫(kù)
2喂击、將獲取到的數(shù)據(jù)返回給服務(wù)層
結(jié)構(gòu)設(shè)計(jì):
DAO層比較簡(jiǎn)單,可能并沒(méi)有通用方法,在這里有一個(gè)點(diǎn)需要注意:
應(yīng)為Go是面向組合開發(fā),所以在DAO的結(jié)構(gòu)設(shè)計(jì)的時(shí)候剂癌,我覺(jué)得這樣是比較合理的:
Type UserDAO struct{
userRds *cache.UserRds
user *models.User
}
因?yàn)檫@里是兩個(gè)數(shù)據(jù)倉(cāng)庫(kù),一個(gè)redis,一個(gè)mysql,所以這里有兩個(gè)字段,對(duì)應(yīng)了兩個(gè)數(shù)據(jù)倉(cāng)庫(kù)的操作,擴(kuò)展的時(shí)候也比較方便
repository層(數(shù)據(jù)倉(cāng)庫(kù)層)
數(shù)據(jù)倉(cāng)庫(kù)層的作用:
1、從數(shù)據(jù)庫(kù)倉(cāng)庫(kù)獲取數(shù)據(jù),redis翰绊、mysql等
2佩谷、向DAO層提供數(shù)據(jù)
結(jié)構(gòu)設(shè)計(jì):
數(shù)據(jù)倉(cāng)庫(kù)層功能單一,但是有兩點(diǎn)需要注意:
1、多數(shù)據(jù)倉(cāng)庫(kù)的初始化連接部分并不應(yīng)該出現(xiàn)在這個(gè)包,這個(gè)包只獲取連接,操作數(shù)據(jù)即可监嗜。
2谐檀、當(dāng)使用多數(shù)據(jù)倉(cāng)庫(kù)時(shí),多個(gè)數(shù)據(jù)參考并不是你想象的那么界限分明,所以不要強(qiáng)制讓他們邊界,你可能寫不下去代碼。
3裁奇、在這個(gè)結(jié)構(gòu)下的包設(shè)計(jì)是以數(shù)據(jù)倉(cāng)庫(kù)為基本標(biāo)準(zhǔn)的.比如你有redis和mysql,那么你應(yīng)該有兩個(gè)包
多層之間如何調(diào)用
你看到主要有路由層,控制層,服務(wù)層,DAO層,數(shù)據(jù)倉(cāng)庫(kù)層,這里面的調(diào)用關(guān)系是:
路由調(diào)用->控制層->服務(wù)層->DAO層->數(shù)據(jù)倉(cāng)庫(kù)層桐猬,不可以越級(jí)調(diào)用和相互調(diào)用,因?yàn)檫@樣調(diào)用會(huì)導(dǎo)致調(diào)用鏈混亂,最后review代碼的時(shí)候,苦不堪言.
conn包
連接包的作用
主要是管理初始化鏈接供外部調(diào)用,比如數(shù)據(jù)庫(kù)初始化鏈接,redis初始化鏈接,以及id生成器初始化鏈接等。
結(jié)構(gòu)設(shè)計(jì)
在這個(gè)包,基本都是平級(jí)關(guān)系,所以只需要?jiǎng)?chuàng)建對(duì)應(yīng)的go文件即可刽肠。
在代碼方面
1溃肪、被調(diào)用方法盡量不進(jìn)行錯(cuò)誤處理和判斷,你的錯(cuò)誤判斷和處理可能是多余的,因?yàn)槟阍谡{(diào)用這個(gè)方法的時(shí)候,你會(huì)再次判斷,存在重復(fù)判斷的可能
2、不要強(qiáng)行使用具名返回值,這可能會(huì)讓你的代碼難看,尤其是在DAO層,你會(huì)發(fā)現(xiàn)使用具名返回值可能會(huì)讓你無(wú)所適從音五。
3惫撰、具名返回值有個(gè)明顯的優(yōu)點(diǎn):調(diào)用方能清楚看到這個(gè)返回值具體是什么含義,這是一個(gè)很重要的優(yōu)點(diǎn),尤其對(duì)于協(xié)作開發(fā)而言。