欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang Model 字段自動化校驗(yàn)設(shè)計(jì)方案

 更新時間:2025年02月17日 11:06:44   作者:Gerald Kwok  
在我們?nèi)粘i_發(fā)中,不可避免的總要去進(jìn)行各種參數(shù)校驗(yàn),但是如果在某個場景中,要校驗(yàn)的字段非常多,并且在其中還有耦合關(guān)系,那么我們手寫校驗(yàn)邏輯就變得非常的低效且難以維護(hù),本篇文檔就基于 DDD 領(lǐng)域模型設(shè)計(jì)的思想下,提供自動化的校驗(yàn)?zāi)P妥侄?感興趣的朋友一起看看吧

背景

在我們?nèi)粘i_發(fā)中,不可避免的總要去進(jìn)行各種參數(shù)校驗(yàn),但是如果在某個場景中,要校驗(yàn)的字段非常多,并且在其中還有耦合關(guān)系,那么我們手寫校驗(yàn)邏輯就變得非常的低效且難以維護(hù)。本篇文檔就基于 DDD 領(lǐng)域模型設(shè)計(jì)的思想下,提供自動化的校驗(yàn)?zāi)P妥侄巍?/p>

常見的字段校驗(yàn)方式

數(shù)據(jù)校驗(yàn)在業(yè)務(wù)邏輯代碼中有著至關(guān)重要的作用,關(guān)系到整個后續(xù)業(yè)務(wù)是否可以正常運(yùn)行。對參數(shù)的校驗(yàn)根據(jù)其具體業(yè)務(wù)邏輯與場景,可以分為字段校驗(yàn)、依賴校驗(yàn)、功能校驗(yàn)與邏輯校驗(yàn)四個部分。

字段校驗(yàn)

字段校驗(yàn)是最常見的校驗(yàn)類型。例如:商品名稱不能超過多少個字符,商品狀態(tài)必須是有效等。

func (e *Shop) ValidateShopName() error {
  	if e.Name != nil && e.Name == "" {
    		return errors.New("商品名稱不能為空。")
 		}
  	if e.Name != nil && utf8.RuneCountInString(e.Name) > constant.MaxShopNameLength {
    		return errors.Errorf("商品名稱長度為 %d, 不能超過 %d ", utf8.RuneCountInString(e.Name), constant.MaxShopNameLength)
  	}
  	return nil
}

依賴校驗(yàn)

依賴校驗(yàn),顧名思義是在業(yè)務(wù)邏輯中依賴了其他模塊。例如,在創(chuàng)建商品信息時,要校驗(yàn)一下商品依賴的商家或供應(yīng)商等信息是否合法。

func (e *Shop) ValidateMerchant() error {
		// 在此方法中可能需要進(jìn)行外部調(diào)用或者查詢 DB 的操作。
  	if e.HasInvalidMerchant() {
    		return errors.New("商家信息存在異常")
  	}
  	return nil
}

功能校驗(yàn)

功能校驗(yàn)例如用戶是否有權(quán)限發(fā)布商品、商品信息是否與其他商品存在沖突等。

func (e *Shop) ValidateUserPermission() error {
  	if e.UserCreateShopWithoutPermission() {
    		return errors.New("用戶無權(quán)限創(chuàng)建商品")
  	}
  	return nil
}

邏輯校驗(yàn)

邏輯校驗(yàn)主要是一些具體的業(yè)務(wù)邏輯。例如在下架商品時,校驗(yàn)是否有新用戶下單等。

func (e *Shop) ValidateCloseShop() error{
  	if e.InvalidShopStatus() {
    		return errors.New("商品已下架")
  	}
  	if e.ExistShopTicket() {
    		return errors.New("有正在進(jìn)行的訂單信息,無法下架")
  	}
  	return nil
}

上面我們列出來常見的四種校驗(yàn)方式,當(dāng)我們在一個復(fù)雜且龐大的業(yè)務(wù)場景需要把各種各樣的校驗(yàn)放在一起去校驗(yàn)時,我們不得不編寫一個龐大的校驗(yàn)函數(shù),把這些單點(diǎn)的校驗(yàn)函數(shù)聚合起來,更有甚者都沒有進(jìn)行子邏輯校驗(yàn)的函數(shù)區(qū)分,就是第一個大函數(shù),把各種各樣的校驗(yàn)邏輯代碼寫到一個函數(shù)中,那么長此以往,校驗(yàn)邏輯就會非常復(fù)雜,無法迭代。

func (e *Shop) ValidateCreateShop() error {
  	if err = e.ValidateShopName(); err != nil {
    		return err
  	}
  	if err = e.ValidateDescrption(); err != nil {
    		return err
  	}
  	if err = e.ValidateImage(); err != nil {
    		return err
  	}
  	if err = e.ValidateMerchant(); err != nil {
    		return err
  	}
  	if err = e.ValidateUserPermission(); err != nil {
    		return err
  	}
  	if err = e.ValidateCloseShop(); err != nil {
    		return err
  	}
  	return nil
}

自動化校驗(yàn)

type Validator struct {
    FieldNames			[]string		// 需要更新的字段
    ValidateNames		[]string		// 需要校驗(yàn)的字段列表
    ValidateFuncList	[]Func() error	// 校驗(yàn)函數(shù)列表
}
func (v *Validator) Validate() error {
    for _, validate := range v.validateFuncList {
        if err := validate(); err != nil {
            return err
        }
    }
    return nil
}
// GetFields2ValidateFuncMap 各個字段的校驗(yàn)函數(shù)在這里擴(kuò)展,在調(diào)用 register 函數(shù)時,會自動注冊
func (a *Aggregate) GetFields2ValidateFuncMap() map[string]func() error {
    return map[string]func() error {
        constant.ShopForCreate:		a.Shop.ValidateCreateShop,
        constant.ShopForUpdate: 	a.Shop.ValidateUpdateShop,
        constant.ShopCanStart:  	a.Shop.CanStart,
        // ... 等等各種校驗(yàn)都可以在這里定義一個聚合函數(shù)列表
    }
}
func DTOToAgg(dto *DTO.Shop) (*shop.Aggregate, error) {
    baseShop := base.NewBaseShop()
    // 先把傳參 model 轉(zhuǎn)化成領(lǐng)域數(shù)據(jù)
    if err = copier.Copy(baseShop, dto); err != nil {
        return nil, errors.Wrap(err, err.Error())
    }
    // New 一個聚合類
    shopAgg := shop.NewShopAggregate(baseShop)
    // 獲取本次傳給領(lǐng)域?qū)ο蟮淖侄?,以及加載要校驗(yàn)的字段
    setFields := GetSetOptionalFields(*dto)
    var validateName []string
    for _, field := range setFields {
        validateName = append(validateName, field)
    }
    shopAgg.SetUpdateFields(setFields)
    // 注冊 validate 函數(shù)
    shopAgg.RegisterValidator(validateName)
    return shopAgg, nil   
}
// 執(zhí)行校驗(yàn)函數(shù)
func (v *Validator) ValidateMultipleFields(ctx context.Context) error {
	for _, validate := range v.validateFuncList {
		if err := validate(); err != nil {
			return err
		}
	}
	return
}

簡單來描述自動校驗(yàn)分為以下幾個步驟:

  • 在接收傳參的轉(zhuǎn)換函數(shù)中,先把本次請求傳入的字段拿到,并且注冊這些字段對應(yīng)的校驗(yàn)函數(shù)。
  • 進(jìn)入到業(yè)務(wù)邏輯處理的函數(shù)中,再次增加一些當(dāng)前業(yè)務(wù)場景需要的特殊校驗(yàn)函數(shù)。
  • 依次執(zhí)行校驗(yàn)函數(shù),觀察是否有報(bào)錯。

到此這篇關(guān)于Golang Model 字段自動化校驗(yàn)設(shè)計(jì)的文章就介紹到這了,更多相關(guān)Golang Model 字段校驗(yàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言編程實(shí)現(xiàn)支持六種級別的日志庫?

    Go語言編程實(shí)現(xiàn)支持六種級別的日志庫?

    這篇文章主要為大家介紹了使用Golang編寫一個支持六種級別的日志庫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Golang當(dāng)中的定時器實(shí)例詳解

    Golang當(dāng)中的定時器實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Golang當(dāng)中定時器的相關(guān)資料,定時器的實(shí)現(xiàn)大家應(yīng)該都遇到過,最近在學(xué)習(xí)golang,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Golang httptest包測試使用教程

    Golang httptest包測試使用教程

    這篇文章主要介紹了Golang httptest包測試使用,httptest包的理念是,非常容易模擬http服務(wù),也就是說模擬響應(yīng)寫(response writer),提供給http處理器(handle),讓我們測試http服務(wù)端和客戶端很容易
    2023-03-03
  • Go 語言數(shù)組和切片的區(qū)別詳解

    Go 語言數(shù)組和切片的區(qū)別詳解

    本文主要介紹了Go 語言數(shù)組和切片的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Golang分布式應(yīng)用定時任務(wù)示例詳解

    Golang分布式應(yīng)用定時任務(wù)示例詳解

    這篇文章主要為大家介紹了Golang分布式應(yīng)用定時任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go到底能不能實(shí)現(xiàn)安全的雙檢鎖(推薦)

    Go到底能不能實(shí)現(xiàn)安全的雙檢鎖(推薦)

    這篇文章主要介紹了Go到底能不能實(shí)現(xiàn)安全的雙檢鎖,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • go?語言爬蟲庫goquery的具體使用

    go?語言爬蟲庫goquery的具體使用

    GoQuery是專為Go語言設(shè)計(jì)的一個強(qiáng)大的HTML解析和查詢庫,本文主要介紹了go語言爬蟲庫goquery的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • golang 格式化輸入輸出操作

    golang 格式化輸入輸出操作

    這篇文章主要介紹了golang 格式化輸入輸出操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 深入了解Golang中的數(shù)據(jù)類型

    深入了解Golang中的數(shù)據(jù)類型

    在計(jì)算機(jī)編程中,數(shù)據(jù)類型是非常重要的一個概念。這篇文章將詳細(xì)介紹 Golang中的數(shù)據(jù)類型,包括基本類型、復(fù)合類型、引用類型以及自定義類型,希望對大家有所幫助
    2023-04-04
  • 一文帶你深入了解Go語言中切片的奧秘

    一文帶你深入了解Go語言中切片的奧秘

    切片是數(shù)組的一個引用,因此切片是引用類型。但自身是結(jié)構(gòu)體,值拷貝傳遞。本文將通過示例帶大家一起探索一下Go語言中切片的奧秘,感興趣的可以了解一下
    2022-11-11

最新評論