PhalGo-ADM思想

2018-01-04 09:27 更新

PhalGo-ADM思想

關(guān)于ADM思想主要是指在API開(kāi)發(fā)中使用API,Domain和Model三層結(jié)構(gòu),PhalGo從PhalApi中學(xué)習(xí)并且推崇這種設(shè)計(jì)模式,這種模式的好處在于分工明確,業(yè)務(wù)復(fù)用,數(shù)據(jù)復(fù)用可以減少?gòu)?fù)雜業(yè)務(wù)重復(fù)的代碼量,很多框架關(guān)心性能,而不關(guān)心人文;很多項(xiàng)目關(guān)心技術(shù),而不關(guān)注業(yè)務(wù)。ADM設(shè)計(jì)就是從業(yè)務(wù)的角度出發(fā)建立的開(kāi)發(fā)規(guī)范.

ADM分工協(xié)作

Api

Api層可以理解為是請(qǐng)求開(kāi)始結(jié)束以及組合業(yè)務(wù)的地方,主要負(fù)責(zé)以下幾件事情:

  1. 獲取請(qǐng)求參數(shù)并且驗(yàn)證請(qǐng)求參數(shù)的有效性
  2. 對(duì)Domain領(lǐng)域?qū)拥膶?shí)現(xiàn)進(jìn)行拼接來(lái)組成整個(gè)接口的業(yè)務(wù)
  3. 對(duì)于返回結(jié)果進(jìn)行處理

我們可以看一個(gè)獲取用戶詳情接口的例子:

func (this *User_Api)GetUserInfo() echo.HandlerFunc {

    return func(c echo.Context) error {
        Request := phalgo.Requser{Context:c}
        Response := phalgo.Response{Context:c}
        defer Request.ErrorLogRecover()

        //獲取請(qǐng)求參數(shù)
        id := Request.GetParam("id").GetInt()
        //拼接領(lǐng)域?qū)訕I(yè)務(wù)
        user, err := this.Domain.User.GetUserInfo(id)
        if err != nil {
            return Response.RetError(err, 400)
        }
        //返回結(jié)果
        return Response.RetSuccess(user)
    }
}

(1)Api接口層應(yīng)該做:

  • 應(yīng)該:對(duì)用戶登錄態(tài)進(jìn)行必要的檢測(cè)
  • 應(yīng)該:控制業(yè)務(wù)場(chǎng)景的主流程,創(chuàng)建領(lǐng)域業(yè)務(wù)實(shí)例,并進(jìn)行調(diào)用
  • 應(yīng)該:進(jìn)行必要的日志紀(jì)錄
  • 應(yīng)該:返回接口結(jié)果

(2)Api接口層不應(yīng)該做:

  • 不應(yīng)該:進(jìn)行業(yè)務(wù)規(guī)則的處理或者計(jì)算
  • 不應(yīng)該:關(guān)心數(shù)據(jù)是否使用緩存,或進(jìn)行緩存相關(guān)的直接操作
  • 不應(yīng)該:直接操作數(shù)據(jù)庫(kù)
  • 不應(yīng)該:將多個(gè)接口合并在一起

Domain

Domain可以稱之為領(lǐng)域?qū)?是ADM(Api-Domain-Model)分層中的橋梁,主要負(fù)責(zé)處理業(yè)務(wù)規(guī)則。Domain層存在的目錄是為了把復(fù)雜業(yè)務(wù)拆分成一個(gè)一個(gè)小模塊然后組織起來(lái)實(shí)現(xiàn)復(fù)雜的業(yè)務(wù),從而達(dá)到代碼復(fù)用,拆分復(fù)雜業(yè)務(wù)的作用.

舉個(gè)栗子

場(chǎng)景:我們?cè)趥鹘y(tǒng)MVC開(kāi)發(fā)的時(shí)候,使用控制器來(lái)處理業(yè)務(wù),我們可能會(huì)寫很多的重復(fù)代碼來(lái)驗(yàn)證用戶提交的信息是否ok,比如完善信息的時(shí)候驗(yàn)證郵箱,在修改用戶信息的時(shí)候也要驗(yàn)證修改的郵箱,在管理的時(shí)候去編輯一個(gè)用戶的時(shí)候也可能在去驗(yàn)證郵箱,這個(gè)時(shí)候我們的驗(yàn)證邏輯代碼已經(jīng)重復(fù)寫在了3個(gè)地方,如果有一個(gè)需求加入了電話號(hào)碼,那么你需要在3個(gè)地方加上對(duì)電話號(hào)碼的驗(yàn)證邏輯

場(chǎng)景一并不難以遇到,而且在復(fù)雜的業(yè)務(wù)情況下重復(fù)使用的業(yè)務(wù)邏輯會(huì)更多,如果我們使用了Domain來(lái)處理用戶修改前的驗(yàn)證那么我們只需要修改這個(gè)驗(yàn)證邏輯加上對(duì)電話號(hào)碼的驗(yàn)證,那么所有需要驗(yàn)證用戶信息的地方就會(huì)全部生效,而不用去做重復(fù)的工作并且避免遺漏的風(fēng)險(xiǎn)

下面是我們獲取User詳情的Domain層的實(shí)現(xiàn),它不僅僅只是可以用在獲取用戶詳情也可以用來(lái)驗(yàn)證用戶ID是否有效,增加代碼復(fù)用性減少修改代價(jià)

func (this *Domain_User)GetUserInfo(id int)(Model.User,error) {

    user, err := this.Model.User.GetInfoById(id)
    if err != nil {
        return user, errors.New("UserInfo There is no")
    }
    return user,nil
}

一個(gè)函數(shù)如果超過(guò)了一屏那將會(huì)影響到閱讀者的理解,使用領(lǐng)域?qū)硬鸱直恐氐臉I(yè)務(wù)可以很好的解決這個(gè)問(wèn)題

Model

Model層想必不用說(shuō)了,就是和數(shù)據(jù)庫(kù)通訊獲取數(shù)據(jù),Model層是單純的不帶任何業(yè)務(wù)只是簡(jiǎn)單的獲取數(shù)據(jù)庫(kù)數(shù)據(jù),我們看一段Model層代碼:

type User struct {
    Id     int       `gorm:"column:aId"`
    Name   string    `gorm:"column:name"`
    Passwd string    `gorm:"column:passwd"`
    Email  string    `gorm:"column:email"`
}

func (User) TableName() string {
    return "user"
}

func (this *User)GetInfoById(id int) (User, error) {

    User := User{}
    err := phalgo.GetORM().Where("id = ?", id).First(&User).Error
    return User, err
}

注意:Model層只應(yīng)該獲取數(shù)據(jù)然后結(jié)束關(guān)于沒(méi)有獲取到數(shù)據(jù),獲取出錯(cuò)等情況拋出到Domain層進(jìn)行處理,這樣可以增加靈活性,比如通過(guò)用戶名是否重復(fù)和通過(guò)用戶名稱獲取ID,一個(gè)返回存在才算異常,一個(gè)返回不存在才算異常,具體更具業(yè)務(wù)不同體現(xiàn)也不同,所以Model層處理并不合適

層級(jí)調(diào)用的順序

整體上講根據(jù)從Api接口層、Domain領(lǐng)域?qū)釉俚組odel數(shù)據(jù)源層的順序進(jìn)行開(kāi)發(fā)。

在開(kāi)發(fā)過(guò)程中,需要注意不能越層調(diào)用也不能逆向調(diào)用,即不能Api調(diào)用Model。而應(yīng)該是上層調(diào)用下層,或者同層級(jí)調(diào)用,也就是說(shuō),我們應(yīng)該:

  • Api層調(diào)用Domain層
  • Domain層調(diào)用Domain層
  • Domain層調(diào)用Model層
  • Model層調(diào)用Model層

為了更明確調(diào)用的關(guān)系,以下調(diào)用是 錯(cuò)誤 的:

  • 錯(cuò)誤的做法1:Api層直接調(diào)用Model層
  • 錯(cuò)誤的做法2: Domain層調(diào)用Api層,也不應(yīng)用將Api層對(duì)象傳遞給Domain層
  • 錯(cuò)誤的做法3: Model層調(diào)用Domain層

這樣的約定,便于我們形成統(tǒng)一的開(kāi)發(fā)規(guī)范,降低學(xué)習(xí)維護(hù)成本。

比如需要添加緩存,我們知道應(yīng)該定位到Model層數(shù)據(jù)源進(jìn)行擴(kuò)展;若發(fā)現(xiàn)業(yè)務(wù)規(guī)則處理不當(dāng),則應(yīng)該進(jìn)入Domain層探其究竟;如果需要對(duì)接口的參數(shù)進(jìn)行調(diào)整,即使是新手也知道應(yīng)該找到對(duì)應(yīng)的Api文件進(jìn)行改動(dòng)。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)