您的位置 首页 golang

Go 中泛型的力量:GORM 的存储库模式

概念证明

我们可以期待在 Go 中拥有一个成熟的 ORM 和 DBAL 框架,比如 Doctrine 吗?

照片由Rajan Alwan在Unsplash上拍摄

经过数月和数年的讨论、实现和概念证明,我们终于达到了我们首选编程语言发生革命的地步。新的 Golang 版本,1.18。在这里。

多年来,每当我们想提供一些通用性和抽象性时,我们都会在 Go 中使用代码生成器。学习什么是 “Golang Way” 对我们中的许多人来说是一段艰难的时期,但它也给了我们很多突破。这是值得的。

现在,新牌摆在桌面上。出现了许多新包,为我们提供了一些关于如何使用可重用代码丰富 Go 生态系统的想法,这将使我们所有人的生活更轻松。而且,类似的东西是我的灵感,它把我带到了基于GORM 库的小型 概念证明 。现在,让我们检查一下。

源代码

当我写这篇文章时,它依赖 GitHub 上的一个 Git 存储库 。该代码将 Go 库表示为概念证明,我打算进一步研究它。尽管如此,它还没有准备好在生产中使用(当然,我当时并不打算提供任何生产支持)。

您可以在链接上查看当前功能,其中较小的示例位于以下代码段中:

带有 PoC 库实际示例的代码片段

为什么我为 PoC 选择了 ORM?

由于我是一名软件开发人员,使用过老式的 OO 编程语言,如 Java 、C# 和 PHP,所以我在 Google 上进行的第一次搜索是关于 Golang 的一些合适的 ORM。请原谅我当时的青春,但那是我的期望。

并不是说我不能没有 ORM。我并不特别欣赏原始 MySQL 查询在代码中的外观。所有这些 字符串 连接对我来说都很难看。

另一方面,我总是喜欢立即投入到编写业务逻辑中,而且我几乎零投入时间思考底层存储。有时我在实施过程中改变主意,并切换到其他类型的存储。这就是 ORM 让我的生活更轻松的地方。

简而言之,ORM 授予我:

  1. 更清洁的代码
  2. 更灵活地选择底层存储的类型
  3. 整个专注于业务逻辑而不是技术细节

Golang 中的 ORM有很多解决方案,我用过其中的大部分。毫不奇怪,GORM 是我使用最多的一个,因为它涵盖了大部分功能。是的,它遗漏了一些众所周知的模式,例如Identity Map、Unit of Work和Lazy Load,但我可以没有它。

尽管如此,我还是错过了存储库模式,因为我不时遇到类似或相同代码块的重复(我讨厌重复自己)。

为此,我有时会使用GNORM库,它的模板逻辑让我可以自由地生成存储库结构。尽管我喜欢 GNORM 提供的想法(很好 的 Golang 方式 !),但不断更新模板以向存储库提供新功能看起来并不好。

我试图提供我的实现,该实现将基于反思并将其提供给 开源社区 我不能再失败了 。行得通,但维护库很痛苦,性能也不是传奇。最后,我从 GitHub 上删除了 git 存储库。

而且,当我在 Go 中放弃这个 ORM 升级时,泛型出现了。 好家伙。 好家伙! 我立即回到绘图板上。

执行

我的部分背景是领域驱动设计。这意味着我喜欢将领域层与基础设施层分离。一些 ORM 将实体模式更像是Row Data Gateway或Active Record。但是,由于它的名称引用了 DDD 模式实体,我们不知何故最终迷失在翻译中,我们倾向于将业务逻辑和技术细节存储在同一个类中。我们制造了一个怪物。

实体模式与数据库表方案映射没有任何关系。无论如何,它与底层存储无关。

所以,我总是在领域层使用实体,在基础设施层使用数据传输对象。我的存储库的签名始终只支持实体,但在内部,它们使用 DTO 将数据映射到数据库并从数据库中获取数据并将它们存储到实体中。它可以保证我们有一个功能性的反腐败层。

在这种情况下,我可以识别出三个接口和结构(如下图所示):

  1. Entity作为领域层业务逻辑的持有者
  2. GormModel作为用于将数据从实体映射到数据库的 DTO
  3. GormRepository作为查询和持久化数据的编排器

UML 图代表了实现的高度概述。

GormModel和两个主要部分GormRepository期望定义其方法签名的泛型类型。使用泛型允许我们将 GormRepository 定义为结构并泛化实现:

GormRepository 的实现。

我不打算为这个概念证明添加或多或少的复杂功能,例如预加载、连接,甚至不限制和偏移。这个想法是用 GORM 库检查 Go 中泛型实现的简单性。

在代码片段中,我们可以看到该GormRepository结构支持插入新记录作为通过身份检索或通过规范查询。规范模式是领域驱动设计的另一种模式,我们可以将其用于多种目的,包括从存储中查询数据。

此处提供的概念证明定义了一个规范接口,该接口提供了一个WHERE子句和其中使用的值。它确实需要对可比较的 运算符 使用一些泛型,并且它可能是未来Query Object的前身:

规范实施的例子。

包的规范部分提供了为存储库提供自定义标准并检索满足它的数据的可能性。使用它可以组合标准、否定它们并进一步扩展它们。

结果

这个实现最终总结了这个概念证明的最终目标,即为从数据库中查询记录提供一个通用接口:

概念证明的最终目标。

关于我的愿望,上面的代码片段提供了一种快速而优雅的方式来以干净易读的形式检索数据。并且不影响性能(显着)。

结论

在 Go 1.18 正式发布后第一次接触泛型是一次重大的更新。最近我一直在与一些挑战作斗争,给这个机会来提出新的想法比我需要的要多。

此外,在长时间的休息后继续写博客是我必须做的事情。再次公开发表意见的感觉真好,我期待你们提供的所有反馈。

文章来源:智云一二三科技

文章标题:Go 中泛型的力量:GORM 的存储库模式

文章地址:https://www.zhihuclub.com/100419.shtml

关于作者: 智云科技

热门文章

网站地图