偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Go Mongox 開(kāi)源庫(kù)設(shè)計(jì)分享:簡(jiǎn)化 MongoDB 開(kāi)發(fā)的最佳實(shí)踐

數(shù)據(jù)庫(kù) MongoDB
go mongox? 是一個(gè)基于泛型的庫(kù),擴(kuò)展了 MongoDB? 的官方框架。通過(guò)泛型技術(shù),它實(shí)現(xiàn)了結(jié)構(gòu)體與 MongoDB? 集合的綁定,旨在提供類型安全和簡(jiǎn)化的數(shù)據(jù)操作。

前言

在使用 Go 語(yǔ)言操作 MongoDB 時(shí),Go 開(kāi)發(fā)者的首選庫(kù)通常是由 MongoDB 官方團(tuán)隊(duì)推出的 mongo-go-driver。這個(gè)庫(kù)是專為 Go 語(yǔ)言開(kāi)發(fā)者打造的,支持 MongoDB 的主要功能,并與最新版本的 MongoDB 兼容。通過(guò) mongo-go-driver,Go 開(kāi)發(fā)者可以便捷地連接數(shù)據(jù)庫(kù),并且能對(duì)集合進(jìn)行查詢、插入、更新、刪除的操作。

盡管 mongo-go-driver 功能強(qiáng)大,但通過(guò)進(jìn)一步封裝,可以在實(shí)際開(kāi)發(fā)中顯著提升開(kāi)發(fā)效率,特別是在復(fù)雜場(chǎng)景下減少代碼冗余和提升可讀性方面。封裝后,可以有效解決以下常見(jiàn)的問(wèn)題:

  • 繁瑣的 BSON 數(shù)據(jù)編寫:構(gòu)建查詢條件、更新文檔或聚合管道時(shí),往往需要編寫大量 BSON 數(shù)據(jù)結(jié)構(gòu)。簡(jiǎn)單格式的 BSON 數(shù)據(jù)較易編寫,但面對(duì)復(fù)雜多層嵌套的文檔時(shí),不僅耗時(shí),還容易出錯(cuò)。即便是一個(gè)小的疏漏,也可能導(dǎo)致結(jié)果偏離預(yù)期,增加了調(diào)試難度。
  • 重復(fù)的反序列化代碼:在查詢不同集合的數(shù)據(jù)時(shí),常常需要編寫重復(fù)的反序列化代碼,不僅增加了代碼冗余,也提升了維護(hù)成本。
  • 聚合管道操作不夠友好:在進(jìn)行聚合操作時(shí),缺少對(duì)聚合管道的直觀支持。開(kāi)發(fā)者需要手動(dòng)編寫復(fù)雜的 BSON 文檔來(lái)定義管道各個(gè)階段,這增加了復(fù)雜性。

因此,我開(kāi)發(fā)了 go mongox 庫(kù)并 針對(duì)這些場(chǎng)景進(jìn)行了優(yōu)化,利用 Go 語(yǔ)言的泛型特性綁定結(jié)構(gòu)體,同時(shí)引入模塊化的 Creator、Updater、Deleter、Finder 和 Aggregator 等功能,分別簡(jiǎn)化插入、更新、刪除、查詢和聚合操作。此外,go mongox 還提供了查詢、更新和聚合語(yǔ)句的構(gòu)建器,以減少代碼冗余,提高開(kāi)發(fā)效率,幫助開(kāi)發(fā)者更專注于業(yè)務(wù)邏輯的實(shí)現(xiàn)。

本文將深入解析 go mongox 開(kāi)源庫(kù)的設(shè)計(jì)思路與實(shí)踐經(jīng)驗(yàn)。

準(zhǔn)備好了嗎?準(zhǔn)備一杯你最喜歡的咖啡或茶,隨著本文一探究竟吧。

倉(cāng)庫(kù)地址:https://github.com/chenmingyong0423/go-mongox

官方文檔:https://go-mongox.dev

go mongox 簡(jiǎn)介

go mongox 是一個(gè)基于泛型的庫(kù),擴(kuò)展了 MongoDB 的官方框架。通過(guò)泛型技術(shù),它實(shí)現(xiàn)了結(jié)構(gòu)體與 MongoDB 集合的綁定,旨在提供類型安全和簡(jiǎn)化的數(shù)據(jù)操作。go mongox 還引入鏈?zhǔn)秸{(diào)用,讓文檔操作更流暢,并且提供了豐富的 BSON 構(gòu)建器和內(nèi)置函數(shù),簡(jiǎn)化了 BSON 數(shù)據(jù)的構(gòu)建。此外,它還支持插件化編程和內(nèi)置多種鉤子函數(shù),為數(shù)據(jù)庫(kù)操作前后的自定義邏輯提供靈活性,增強(qiáng)了應(yīng)用的可擴(kuò)展性和可維護(hù)性。

功能特性

  • 泛型的 MongoDB 集合
  • 文檔的 CRUD 操作
  • 聚合操作
  • 內(nèi)置基本的 Model 結(jié)構(gòu)體,自動(dòng)化更新默認(rèn)的 field 字段
  • 支持 BSON 數(shù)據(jù)的構(gòu)建
  • 支持結(jié)構(gòu)體 tag 校驗(yàn)
  • 內(nèi)置 Hooks
  • 支持插件化編程

泛型的 Collection

為了將結(jié)構(gòu)體與 MongoDB 的集合進(jìn)行綁定,mongox 定義了一個(gè)泛型 Collection 結(jié)構(gòu)體。通過(guò)泛型參數(shù) T any,它提供了類型安全的 MongoDB 集合操作,同時(shí)保留了對(duì)原始 *mongo.Collection 的訪問(wèn)。

type Collection[T any] struct {
	collection *mongo.Collection
}

func (c *Collection[T]) Collection() *mongo.Collection {
	return c.collection
}

func NewCollection[T any](collection *mongo.Collection) *Collection[T] {
	return &Collection[T]{collection: collection}
}

設(shè)計(jì)特點(diǎn)與優(yōu)勢(shì)

  • 類型安全

通過(guò)泛型,Collection[T] 可以直接操作不同的數(shù)據(jù)模型類型 T,避免了傳統(tǒng)方法中的類型斷言和轉(zhuǎn)換,提高了代碼安全性和可讀性。

  • 代碼復(fù)用性
  • 泛型支持高度通用的邏輯封裝,使得 CRUD 方法只需實(shí)現(xiàn)一次,即可適配所有數(shù)據(jù)模型類型。這種復(fù)用性顯著減少了開(kāi)發(fā)和維護(hù)成本。

  • 兼容性

  • Collection() 方法允許用戶直接訪問(wèn)底層的 *mongo.Collection,保留了原始功能,兼容復(fù)雜的 MongoDB 操作需求。

CRUD 操作器

圖片圖片

mongox 內(nèi)置了五個(gè)獨(dú)立的操作器類型:Finder、Creator、Updater、Deleter 和 Aggregator,分別負(fù)責(zé)集合的 查找、創(chuàng)建、更新、刪除 和 聚合 操作。這些操作器實(shí)例通過(guò) Collection[T] 對(duì)象提供,且每個(gè)操作器聚焦于一個(gè)具體的集合操作。

func (c *Collection[T]) Finder() *finder.Finder[T] {
	return finder.NewFinder[T](c.collection)
}

func (c *Collection[T]) Creator() *creator.Creator[T] {
	return creator.NewCreator[T](c.collection)
}

func (c *Collection[T]) Updater() *updater.Updater[T] {
	return updater.NewUpdater[T](c.collection)
}

func (c *Collection[T]) Deleter() *deleter.Deleter[T] {
	return deleter.NewDeleter[T](c.collection)
}
func (c *Collection[T]) Aggregator() *aggregator.Aggregator[T] {
	return aggregator.NewAggregator[T](c.collection)
}
// 省略細(xì)節(jié)代碼

type Finder[T any] struct {}

type Creator[T any] struct {}

type Updater[T any] struct {}

type Deleter[T any] struct {}

type Aggregator[T any] struct {}

設(shè)計(jì)特點(diǎn)與優(yōu)勢(shì):

  • 單一職責(zé)

每個(gè)操作器聚焦于特定的集合操作,符合單一職責(zé)原則(SRP)。通過(guò)劃分不同的操作器模塊,降低了功能間的耦合度。

  • 擴(kuò)展性強(qiáng)
  • 每個(gè)操作器獨(dú)立實(shí)現(xiàn)其功能邏輯,便于擴(kuò)展。例如:如果需要新增批量更新功能,只需擴(kuò)展 Updater 類型的功能。新增的功能模塊不會(huì)影響其他模塊的穩(wěn)定性。

  • 鏈?zhǔn)秸{(diào)用支持

  • 操作器支持鏈?zhǔn)秸{(diào)用,便于組合復(fù)雜的集合操作,讓集合操作的代碼寫起來(lái)更加絲滑。

使用示例

  • Finder
user, err := userColl.Finder().
    Filter(query.Id("60e96214a21b1b0001c3d69e")).
    FindOne(context.Background())
  • Creator
insertOneResult, err := userColl.Creator().
    InsertOne(context.Background(), &User{Name: "Mingyong Chen", Age: 18})
  • Updater
updateResult, err := userColl.Updater().
		Filter(query.Id("60e96214a21b1b0001c3d69e")).
		Updates(update.Set("name", "Mingyong Chen")).
		UpdateOne(context.Background())
  • Deleter
deleteResult, err := userColl.Deleter().
    Filter(query.Id("60e96214a21b1b0001c3d69e")).
    DeleteOne(context.Background())
  • Aggregator
// 忽略年齡字段,只查詢名字
users, err := userColl.Aggregator().
    Pipeline(aggregation.NewStageBuilder().Project(bsonx.M("age", 0)).Build()).
    Aggregate(context.Background())

鏈?zhǔn)秸{(diào)用

在設(shè)計(jì)支持鏈?zhǔn)秸{(diào)用的操作器結(jié)構(gòu)體時(shí),需要明確結(jié)構(gòu)體的職責(zé)和需要傳遞的參數(shù)。操作器支持鏈?zhǔn)秸{(diào)用的本質(zhì)是 逐步構(gòu)建操作所需的參數(shù),最終在調(diào)用執(zhí)行方法時(shí)將參數(shù)完整地傳遞并執(zhí)行操作。

以 Updater 為例,它專注于 更新 操作,在這一場(chǎng)景中,鏈?zhǔn)秸{(diào)用的目標(biāo)是通過(guò)連續(xù)調(diào)用方法來(lái)逐步完成以下任務(wù):

  • 設(shè)置查詢條件(filter):指定需要更新的文檔范圍。
  • 定義更新內(nèi)容(updates):明確如何修改文檔的字段。
  • 執(zhí)行更新操作:將構(gòu)建好的參數(shù)應(yīng)用到數(shù)據(jù)庫(kù)的更新方法中。

以下是 Updater 的實(shí)現(xiàn):

type Updater[T any] struct {
	collection  *mongo.Collection
	filter      any
	updates     any
}

func (u *Updater[T]) Filter(filter any) *Updater[T] {
	u.filter = filter
	return u
}

func (u *Updater[T]) Updates(updates any) *Updater[T] {
	u.updates = updates
	return u
}

func (u *Updater[T]) UpdateOne(ctx context.Context, opts ...options.Lister[options.UpdateOptions]) (*mongo.UpdateResult, error) {
  // 忽略細(xì)節(jié)代碼
}

func (u *Updater[T]) UpdateMany(ctx context.Context, opts ...options.Lister[options.UpdateOptions]) (*mongo.UpdateResult, error) {
  // 忽略細(xì)節(jié)代碼
}

func (u *Updater[T]) Upsert(ctx context.Context, opts ...options.Lister[options.UpdateOptions]) (*mongo.UpdateResult, error) {
  // 忽略細(xì)節(jié)代碼
}

設(shè)計(jì)特點(diǎn)與優(yōu)勢(shì):

  • 簡(jiǎn)潔流暢的參數(shù)構(gòu)建

每個(gè)鏈?zhǔn)椒椒ㄘ?fù)責(zé)構(gòu)建單一的操作參數(shù)(如 Filter 構(gòu)建查詢條件,Updates 構(gòu)建更新內(nèi)容),通過(guò)鏈?zhǔn)秸{(diào)用逐步完成復(fù)雜操作的參數(shù)準(zhǔn)備,簡(jiǎn)化了方法的使用。

  • 符合直覺(jué)的調(diào)用方式
  • 鏈?zhǔn)秸{(diào)用的代碼邏輯接近自然語(yǔ)言表達(dá)。例如:

updateResult, err := userColl.Updater().
		Filter(query.Id("60e96214a21b1b0001c3d69e")).
		Updates(update.Set("name", "Mingyong Chen")).
		UpdateOne(context.Background())
  • 高擴(kuò)展性與一致性

鏈?zhǔn)椒椒ň哂幸恢碌脑O(shè)計(jì)風(fēng)格,新增功能時(shí)只需擴(kuò)展現(xiàn)有鏈?zhǔn)椒椒ǎ瑹o(wú)需改動(dòng)底層實(shí)現(xiàn)。例如,可以輕松為 Updater 增加 Hook 或日志功能。

對(duì)于其他操作器,例如 Creator 和 Finder 等,其設(shè)計(jì)理念也是類似的。

BSON 構(gòu)建

圖片圖片

mongox 庫(kù)提供了強(qiáng)大的 BSON 數(shù)據(jù)構(gòu)建功能,幫助開(kāi)發(fā)者簡(jiǎn)化與 MongoDB 交互時(shí)復(fù)雜 BSON 數(shù)據(jù)的構(gòu)建。為了解決開(kāi)發(fā)中常見(jiàn)的構(gòu)建復(fù)雜查詢、更新內(nèi)容以及聚合管道時(shí)的繁瑣問(wèn)題,mongox 將功能劃分為以下幾個(gè)包:

  • query 包

專用于構(gòu)建查詢條件的 BSON 數(shù)據(jù)。

提供了一系列鏈?zhǔn)綐?gòu)建器和函數(shù),支持條件拼接($and、$or)、范圍查詢($gt、$lt)等復(fù)雜查詢。

  • update 模塊
  • 專注于構(gòu)建更新操作的 BSON 數(shù)據(jù),例如 $set、$inc 等。

  • 通過(guò)清晰的鏈?zhǔn)讲僮鳎瑤椭_(kāi)發(fā)者快速構(gòu)建更新內(nèi)容。

  • aggregation 模塊

  • 專注于構(gòu)建 MongoDB 的聚合管道(pipeline)。

  • 提供了分步構(gòu)建復(fù)雜聚合管道的工具,支持 $match、$group、$project 等。

  • bsonx 模塊

  • 提供了一系列便捷函數(shù)和通用構(gòu)建器,用于快速構(gòu)建各種 BSON 數(shù)據(jù),覆蓋查詢、更新和聚合之外的常見(jiàn)需求。

query 包

為了支持簡(jiǎn)單構(gòu)建和復(fù)雜構(gòu)建,query 包提供兩種構(gòu)建模式:直接函數(shù)構(gòu)建和構(gòu)建器構(gòu)建。

為了支持簡(jiǎn)單查詢語(yǔ)句和復(fù)雜查詢語(yǔ)句的構(gòu)建,query 包提供了兩種靈活的構(gòu)建模式:直接函數(shù)構(gòu)建 和 構(gòu)建器構(gòu)建。這兩種方式的結(jié)合滿足了從快速構(gòu)建到復(fù)雜邏輯表達(dá)的多種需求。

直接函數(shù)構(gòu)建

通過(guò)提供簡(jiǎn)單的函數(shù),開(kāi)發(fā)者可以快速構(gòu)建包含單個(gè)操作符的 BSON 查詢條件。這種方式適用于無(wú)需組合邏輯的簡(jiǎn)單查詢。

func Eq(key string, value any) bson.D {
	return bson.D{bson.E{Key: key, Value: bson.D{{Key: "$eq", Value: value}}}}
}

func Lt(key string, value any) bson.D {
	return bson.D{bson.E{Key: key, Value: bson.D{{Key: "$lt", Value: value}}}}
}

// 忽略其他函數(shù)實(shí)現(xiàn)

使用示例:

/*
 {
   "name": "陳明勇"
 }
*/
eq := query.Eq("name", "陳明勇")

構(gòu)建器構(gòu)建

對(duì)于復(fù)雜查詢邏輯的構(gòu)建,mongox 提供了功能強(qiáng)大的 Builder 構(gòu)建器,通過(guò)鏈?zhǔn)秸{(diào)用的方式逐步構(gòu)建復(fù)雜的 BSON 數(shù)據(jù)。

func NewBuilder() *Builder {
	query := &Builder{
		data: bson.D{},
		err:  make([]error, 0),
	}
	query.comparisonQueryBuilder = comparisonQueryBuilder{parent: query}
	query.logicalQueryBuilder = logicalQueryBuilder{parent: query}
	query.elementQueryBuilder = elementQueryBuilder{parent: query}
	query.arrayQueryBuilder = arrayQueryBuilder{parent: query}
	query.evaluationQueryBuilder = evaluationQueryBuilder{parent: query}
	query.projectionQueryBuilder = projectionQueryBuilder{parent: query}
	return query
}

type Builder struct {
	data bson.D
	comparisonQueryBuilder
	logicalQueryBuilder
	elementQueryBuilder
	arrayQueryBuilder
	evaluationQueryBuilder
	projectionQueryBuilder
}

func (b *Builder) Build() bson.D {
	return b.data
}

構(gòu)建器的核心是通過(guò)組合子構(gòu)建器(如 comparisonQueryBuilder)實(shí)現(xiàn)不同操作符的邏輯。每個(gè)子構(gòu)建器提供其專屬的鏈?zhǔn)椒椒ǎ珺uilder 通過(guò)組合這些方法形成完整的功能集。

子構(gòu)建器的實(shí)現(xiàn)(示例)

type comparisonQueryBuilder struct {
	parent *Builder
}

func (b *comparisonQueryBuilder) Eq(key string, value any) *Builder {
	e := bson.E{Key: EqOp, Value: value}
	if !b.parent.tryMergeValue(key, e) {
		b.parent.data = append(b.parent.data, bson.E{Key: key, Value: bson.D{e}})
	}
	return b.parent
}

func (b *comparisonQueryBuilder) Gt(key string, value any) *Builder {
	e := bson.E{Key: GtOp, Value: value}
	if !b.parent.tryMergeValue(key, e) {
		b.parent.data = append(b.parent.data, bson.E{Key: key, Value: bson.D{e}})
	}
	return b.parent
}

func (b *comparisonQueryBuilder) Lt(key string, value any) *Builder {
	e := bson.E{Key: LtOp, Value: value}
	if !b.parent.tryMergeValue(key, e) {
		b.parent.data = append(b.parent.data, bson.E{Key: key, Value: bson.D{e}})
	}
	return b.parent
}

構(gòu)建器主功能:

  • 鏈?zhǔn)秸{(diào)用:開(kāi)發(fā)者可以通過(guò)連續(xù)調(diào)用 Builder 提供的方法來(lái)逐步構(gòu)建查詢條件。
  • 復(fù)雜邏輯管理:不同的查詢邏輯(如比較、邏輯、數(shù)組操作)由子構(gòu)建器獨(dú)立實(shí)現(xiàn),避免了功能混亂。

使用示例:

/*
      {
          "age": {
              "$gt": {
                  "$numberInt": "18"
              },
              "$lt": {
                  "$numberInt": "30"
              }
          }
      }
  */
query.NewBuilder().Gt("age", 18).Lt("age", 30).Build()

類似于 query 包,mongox 中的其他模塊(如 update、aggregation、bsonx)也采用了類似的設(shè)計(jì)模式,提供了直接函數(shù)構(gòu)建和構(gòu)建器構(gòu)建兩種方式,支持鏈?zhǔn)秸{(diào)用以簡(jiǎn)化復(fù)雜邏輯的構(gòu)建。接下來(lái)就不對(duì)它們多做介紹了。

設(shè)計(jì)特點(diǎn)與優(yōu)勢(shì)

  • 靈活性:

提供兩種構(gòu)建模式,分別滿足簡(jiǎn)單場(chǎng)景和復(fù)雜邏輯場(chǎng)景。

直接函數(shù)構(gòu)建模式適合快速開(kāi)發(fā),構(gòu)建器模式支持復(fù)雜需求。

  • 職責(zé)分離:
  • 不同類型的查詢操作(如比較、邏輯、數(shù)組)由獨(dú)立的子構(gòu)建器負(fù)責(zé)實(shí)現(xiàn),代碼結(jié)構(gòu)清晰,易于擴(kuò)展。

  • 鏈?zhǔn)秸{(diào)用:

  • 構(gòu)建器支持鏈?zhǔn)秸{(diào)用,用戶可以直觀地通過(guò)方法鏈逐步構(gòu)建查詢條件,語(yǔ)義清晰,代碼自然流暢。

  • 復(fù)用性與擴(kuò)展性:

  • 新增操作符只需擴(kuò)展對(duì)應(yīng)子構(gòu)建器,而無(wú)需改動(dòng)核心邏輯。

  • 不同子構(gòu)建器之間可獨(dú)立維護(hù),降低了代碼的耦合度。

插件化編程

mongox 支持插件化編程,它提供了一種靈活的方式在數(shù)據(jù)庫(kù)操作的前后插入自定義的邏輯,從而增強(qiáng)應(yīng)用的可擴(kuò)展性和可維護(hù)性。非常適合用于以下場(chǎng)景:

  • 默認(rèn)字段填充:填充 _id 和創(chuàng)建時(shí)間以及更新時(shí)間的字段值。
  • 日志記錄:記錄操作前后的信息。
  • 數(shù)據(jù)驗(yàn)證:在插入或更新前檢查數(shù)據(jù)的有效性。
  • 權(quán)限校驗(yàn):根據(jù)業(yè)務(wù)需求在操作前校驗(yàn)用戶權(quán)限。

核心設(shè)計(jì):Callback 結(jié)構(gòu)體

Callback 是 mongox 插件化編程的核心。它通過(guò)一系列鉤子屬性(如 beforeInsert、afterInsert 等)將自定義邏輯綁定到集合操作的特定階段。

// 全局回調(diào)管理器
var Callbacks = initializeCallbacks()

// 初始化 Callback
func initializeCallbacks() *Callback {
	return &Callback{
		beforeInsert: make([]callbackHandler, 0),
		afterInsert:  make([]callbackHandler, 0),
		beforeUpdate: make([]callbackHandler, 0),
		afterUpdate:  make([]callbackHandler, 0),
		beforeDelete: make([]callbackHandler, 0),
		afterDelete:  make([]callbackHandler, 0),
		beforeUpsert: make([]callbackHandler, 0),
		afterUpsert:  make([]callbackHandler, 0),
		beforeFind:   make([]callbackHandler, 0),
		afterFind:    make([]callbackHandler, 0),
	}
}

type Callback struct {
	beforeInsert []callbackHandler
	afterInsert  []callbackHandler
	beforeUpdate []callbackHandler
	afterUpdate  []callbackHandler
	beforeDelete []callbackHandler
	afterDelete  []callbackHandler
	beforeUpsert []callbackHandler
	afterUpsert  []callbackHandler
	beforeFind   []callbackHandler
	afterFind    []callbackHandler
}

type callbackHandler struct {
	name string
	fn   CbFn
}

type CbFn func(ctx context.Context, opCtx *operation.OpContext, opts ...any) error

// operation_type.go
type OpContext struct {
	Col *mongo.Collection `opt:"-"`
	Doc any
	// filter also can be used as query
	Filter       any
	Updates      any
	Replacement  any
	MongoOptions any
	ModelHook    any
}

func (c *Callback) Execute(ctx context.Context, opCtx *operation.OpContext, opType operation.OpType, opts ...any) error {
	switch opType {
	  // 忽略實(shí)現(xiàn)細(xì)節(jié),根據(jù)操作類型 opType 執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。
	}
	return nil
}
  • 鉤子類型:

每個(gè)集合操作(如插入、更新、查詢等)都有 before 和 after 兩種鉤子。

鉤子以切片形式存儲(chǔ),支持注冊(cè)多個(gè)回調(diào)函數(shù),這些函數(shù)將按順序執(zhí)行。

  • callbackHandler:
  • name:鉤子函數(shù)的名稱,便于管理和調(diào)試。

  • fn:具體的回調(diào)函數(shù),實(shí)現(xiàn)自定義邏輯。

  • 包含兩個(gè)屬性:

  • CbFn 回調(diào)函數(shù):

  • ctx:上下文,用于控制回調(diào)的生命周期。

  • opCtx:操作上下文,包含數(shù)據(jù)庫(kù)操作相關(guān)的參數(shù)。

  • opts:可選參數(shù),用于傳遞額外信息。

  • 定義了統(tǒng)一的函數(shù)簽名,參數(shù)包括:

  • 回調(diào)執(zhí)行邏輯

  • 通過(guò) Execute 方法,根據(jù)操作類型查找對(duì)應(yīng)的鉤子列表,并按順序執(zhí)行回調(diào)。

  • 如果任何一個(gè)回調(diào)函數(shù)返回錯(cuò)誤,則中斷執(zhí)行并返回錯(cuò)誤信息。

操作上下文:OpContext

OpContext 是回調(diào)函數(shù)的核心參數(shù),提供了集合操作相關(guān)的詳細(xì)信息,供開(kāi)發(fā)者在回調(diào)函數(shù)中靈活使用。

type OpContext struct {
	Col *mongo.Collection `opt:"-"`  // MongoDB 集合實(shí)例
	Doc any                          // 文檔
	Filter       any                 // 查詢條件
	Updates      any                 // 更新內(nèi)容
	Replacement  any                 // 替換內(nèi)容
	MongoOptions any                 // MongoDB 原生選項(xiàng)
	ModelHook    any                 // 用于判斷綁定的結(jié)構(gòu)體是否實(shí)現(xiàn) Model Hook
}

核心字段說(shuō)明:

  • Col:當(dāng)前操作的集合實(shí)例。
  • Doc:文檔。
  • Filter:操作的查詢條件,如查找、更新或刪除時(shí)使用。
  • Updates:更新內(nèi)容。
  • Replacement:替換操作的文檔內(nèi)容。
  • MongoOptions:傳遞 MongoDB 原生的操作選項(xiàng)。
  • ModelHook:與模型相關(guān)的自定義上下文,可擴(kuò)展使用。

使用示例

  • 注冊(cè)與刪除回調(diào)
// 注冊(cè)插件
mongox.RegisterPlugin("after find", func(ctx context.Context, opCtx *operation.OpContext, opts ...any) error {
    if user, ok := opCtx.Doc.(*User); ok {
        fmt.Println(user)
    }
    if users, ok := opCtx.Doc.([]*User); ok {
        fmt.Println(users)
    }
    return nil
}, operation.OpTypeAfterFind)

// 刪除插件
mongox.RemovePlugin("after find", operation.OpTypeAfterFind)
  • 執(zhí)行回調(diào) 在實(shí)際的集合操作中,調(diào)用 Execute 方法以運(yùn)行注冊(cè)的回調(diào):
err = callback.GetCallback().Execute(ctx, globalOpContext, opType)
if err != nil {
	return
}

設(shè)計(jì)特點(diǎn)與優(yōu)勢(shì)

  • 靈活性:

每個(gè)操作類型支持多個(gè) before 和 after 鉤子,開(kāi)發(fā)者可以自由組合和擴(kuò)展??蓴U(kuò)展性:

回調(diào)以切片形式存儲(chǔ),允許動(dòng)態(tài)增加、移除或替換鉤子函數(shù)。

  • 統(tǒng)一性:
  • 回調(diào)函數(shù)使用統(tǒng)一簽名,結(jié)合 OpContext 提供全面的操作上下文,便于調(diào)試和擴(kuò)展。

  • 解耦性:

  • 集合操作與業(yè)務(wù)邏輯分離,回調(diào)機(jī)制將非核心功能獨(dú)立實(shí)現(xiàn),保持代碼簡(jiǎn)潔和高可維護(hù)性。

小結(jié)

本文詳細(xì)介紹了 go mongox 開(kāi)源庫(kù)的設(shè)計(jì)思路與實(shí)踐經(jīng)驗(yàn),涵蓋了多個(gè)核心模塊的設(shè)計(jì)與實(shí)現(xiàn),包括以下內(nèi)容:

  • Collection[T] 的設(shè)計(jì)與實(shí)現(xiàn):類型安全的集合封裝;
  • CRUD 操作器(如 Finder、Creator、Updater、Deleter、Aggregator):模塊化的增刪改查設(shè)計(jì);
  • 鏈?zhǔn)秸{(diào)用的實(shí)現(xiàn):簡(jiǎn)化復(fù)雜操作的流暢調(diào)用設(shè)計(jì);
  • BSON 數(shù)據(jù)構(gòu)建包(query、update、aggregate):高效構(gòu)建查詢、更新與聚合相關(guān)的 BSON 數(shù)據(jù);
  • 插件化編程的設(shè)計(jì):通過(guò)鉤子機(jī)制靈活擴(kuò)展功能。

雖然開(kāi)發(fā)一個(gè)功能類似 go mongox 的庫(kù)并不復(fù)雜,但如何通過(guò)精心設(shè)計(jì)實(shí)現(xiàn)出色的擴(kuò)展性、易用性和復(fù)用性,才是開(kāi)發(fā)者需要深思的問(wèn)題。希望這篇文章能為你提供實(shí)用的思路與經(jīng)驗(yàn)。

責(zé)任編輯:武曉燕 來(lái)源: 程序員陳明勇
相關(guān)推薦

2024-01-25 08:11:31

2010-11-02 14:11:15

SilverlightWPF微軟開(kāi)發(fā)

2024-08-21 08:02:47

2011-04-06 09:33:40

Push動(dòng)互聯(lián)網(wǎng)

2025-08-28 10:05:00

Go庫(kù)開(kāi)發(fā)

2016-12-27 08:49:55

API設(shè)計(jì)策略

2022-06-22 06:49:39

Hertz開(kāi)源HTTP 框架

2023-05-12 23:31:06

2014-09-01 09:57:11

Go產(chǎn)品環(huán)境最佳語(yǔ)言

2012-05-24 10:19:42

QQ瀏覽器Android設(shè)計(jì)分享

2010-12-02 14:32:43

Mobile Web移動(dòng)互聯(lián)網(wǎng)移動(dòng)Web設(shè)計(jì)

2021-10-18 06:54:47

Go開(kāi)源庫(kù)業(yè)務(wù)

2012-02-07 09:17:13

2023-08-31 08:00:00

測(cè)試開(kāi)發(fā)

2013-06-13 09:21:31

RESTful APIRESTfulAPI

2016-05-09 09:26:06

架構(gòu)ios網(wǎng)絡(luò)層

2019-11-11 14:15:36

谷歌開(kāi)源開(kāi)發(fā)

2011-06-20 06:22:18

ibmdwDB2

2025-10-09 01:22:00

MySQL數(shù)據(jù)庫(kù)ID字段

2010-10-28 09:05:42

SilverlightXAML
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)