1

我正在尝试学习领域驱动设计(DDD)。而且我不明白如何从持久性存储中构造域模型。我正在制作没有公共设置器的域模型,以保持我的状态安全和一致,但另一方面,要从持久性存储构建它们,我需要拥有这些设置器。在“实施DDD”中,只要我使用ORM工具就可以。但是如果我不想使用 ORM,实际上我想使用 NoSQL 怎么办。我可能会使用事件溯源。如果大家有更好的建议。在这种情况下,最佳做法是什么。

4

3 回答 3

0

如何从持久存储构建域模型?

我的建议:如果您的域有点复杂,请不要这样做。

DB模型是为了存储数据而设计的模型。如果您由此生成域模型,结果将是一个贫血模型:没有任何行为的实体。
考虑到 DDD 原则设计的领域模型将产生一个由实体和具有行为的值对象组成的丰富模型。这些行为将帮助您实现属于特定有界上下文的用例。

话虽如此,如果您的有界上下文仅是 CRUD,没有域复杂性,那么这是一种完全有效的方法。请记住,DDD 不会强制选择任何架构。您有很多战术模式,您可能想要使用或不使用取决于您的有限上下文复杂性。

于 2020-11-04T10:46:19.383 回答
0

我相信您正在将域模型与数据传输对象 (DTO) 混合在一起。存储库不使用(参考)域模型,它使用 DTO。

通常,您会将 IRepository 实例传递给业务模型对象的 ctor,然后模型本身可以使用存储库来获取数据(以 DTO 的形式),直接设置其私有属性,或者根据业务需要使用其方法来验证数据。您传递 IRepository 实例是因为您可能还需要保存数据,而不仅仅是加载它。因此,为了让业务对象能够知道如何保存经过验证的数据,它需要引用存储库实例。

或者,如果您想对此非常纯粹,并且不传递存储库实例,并将加载/保存留给应用程序层,那么您将在应用程序层的某处调用 repository.Getxxx 并将数据(作为 DTO)传递给业务模型医生。

于 2020-11-02T13:42:46.890 回答
0

首先,您使用什么数据库并不重要,因此您可以使用 SQL 数据库或 NoSQL,这同样适用于 ORM 或低级客户端。

您的存储库需要做的是收集数据并将其传递给域模型的构造函数,因此不需要公共设置器。我用一个简单的例子添加了一些伪代码:

class UserEntity:
  public function constructor(name, email)
    this._set_name(name)
    this._set_email(email)

  private function _set_name(name)
    this.name = name

  private function _set_email(email)
    this.email = email


class Repository:
  public static function get_by_email(a_email)
    row = client.sql("SELECT * FROM foo WHERE email=%", a_email)
    return UserEntity(name=row["name"], email=row["email"])
于 2020-11-01T15:59:18.087 回答