Go中的微服务:存储库模式

231 阅读3分钟

什么是存储库模式?

根据Martin Fowler在《企业应用架构模式》(第一版)中所说,存储库

在领域和数据映射层之间进行调解,使用一个类似于集合的接口来访问领域对象。

他继续说。

从概念上讲,存储库封装了数据存储中持久化的对象集以及对它们进行的操作,为持久化层提供了一个更加面向对象的视图。存储库还支持实现领域和数据映射层之间的干净分离和单向依赖的目标*。***

领域驱动设计(DDD)中,Repository模式与另一个DDD术语Aggregate有关,Martin Fowler将其定义为。

......可以被当作一个单元的领域对象的集群。

聚合体是数据存储转移的基本要素--你要求加载或保存整个聚合体。交易不应该跨越聚合体的边界。

存储库 聚合体齐头并进,通常是一对一地执行,正如微软所说。

需要再次强调的是,你应该只为每个聚合根定义一个存储库。为了实现聚合根保持聚合内所有对象之间交易一致性的目标,你永远不应该为数据库中的每张表创建一个存储库

所有这些都是需要指出的,因为我们将要实现的代码就是遵循这些想法。


为我们的 "待办事项 "领域实现资源库

我们的 "To Do微服务 "实现了一个To Do域,需要持久化数据。我们将定义一个负责与持久化层直接交互的类型,它也恰好代表一个领域实体,这个类型将实现代表具体业务交互的方法。

要实现的方法取决于我们正在研究的实体和我们试图代表的集合。在这种情况下,我们将专注于Task ,资源库将定义3个方法。

// TaskRepository defines the datastore handling persisting Task records.
type TaskRepository interface {
	Create(ctx context.Context, description string, priority internal.Priority, dates internal.Dates) (internal.Task, error)
	Find(ctx context.Context, id string) (internal.Task, error)
	Update(ctx context.Context, id string, description string, priority internal.Priority, dates internal.Dates, isDone bool) error
}

上面,我提到了具体的业务交互,但TaskRepository 定义的是字面上的CRU 行动,对我们的To Do领域来说是可以预期的,然而,重要的是要始终记住,要从我们的业务领域和它是如何处理这些行动的角度来考虑,如果CRUD风格对我们试图实现的东西有效,那应该是没问题的,但是,就像我们之前提到的,我们需要确保我们不会开始添加类似CRUD的资源库,而不是代表我们正在实现的领域。

我们实现TaskRepository interface 的类型将被定义为 postgresql.Task.用来代表包含这个这个类型的包的命名是遵循我们之前描述的准则,在这里我们使用技术名称,在这个例子中:postgresql

在幕后,postgresql.Task 使用由以下代码生成的 sqlc生成的代码与PostgreSQL数据库进行实际交互,以正确实现CREATESELECTUPDATE

总结

存储库模式是分离业务领域层和持久层的一种强有力的方式,它允许我们准确地指出我们的数据是如何进出数据存储的,同时隐藏了该层可能带来的复杂性。

重要的是要记住,并不是所有的实体都需要一个存储库,而只是那些代表领域实体的集合,碰巧需要作为一个单元来工作。