问题描述
我正在尝试学习域驱动设计(DDD)。而且我不明白如何从持久性存储中构造域模型。我要在没有公共设置器的情况下制作域模型,以便保持状态的安全性和一致性,但是,另一方面,要从持久性存储中构造它们,我需要拥有这些设置器。在“实施DDD”中,只要我使用ORM工具就可以。但是,如果我不想使用ORM,实际上我想使用Nosql。我可能会使用事件来源。如果你们有更好的建议。在这种情况下的最佳做法是什么。
解决方法
首先,使用什么数据库都没有关系,因此您可以使用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"])
,
我相信您正在将领域模型与数据传输对象(DTO)混合在一起。存储库不使用(参考)域模型,而是使用DTO。
通常,您需要将IRepository实例传递给业务模型对象的ctor,然后模型本身可以使用存储库来获取数据(以DTO的形式),直接设置其私有属性或使用其方法来验证数据(如果需要)通过业务。您传递IRepository实例是因为您可能还需要保存数据,而不仅仅是加载它。因此,为了使业务对象能够知道如何保留经过验证的数据,它需要引用存储库实例。
或者,如果您想真正做到这一点,并且不传递存储库实例,而将加载/保存留给应用程序层,则可以在应用程序层的某个地方调用repository.Getxxx并传递数据(作为DTO)到业务模型中心。
,如何从持久性存储中构建域模型?
我的建议:如果您的域有点复杂,请不要这样做。
DB模型是为了存储数据而设计的模型。如果从中生成域模型,则结果将是anemic model:实体,没有任何行为。
考虑到DDD原理设计的域模型将导致由具有行为的实体和值对象组成的丰富模型。这些行为将帮助您实现属于特定有界上下文的用例。
也就是说,如果您的有限上下文是CRUD,而没有域复杂性,则这是一种完全有效的方法。请记住,DDD不会强制选择任何体系结构。根据您受限的上下文复杂性,您可能会想使用或不使用很多战术模式。