单独的数据模型时,如何从存储库返回域对象?
作者:互联网
更新资料
我的研究告诉我,我应该使用数据映射器:https://martinfowler.com/eaaCatalog/dataMapper.html.数据映射器是否已注入到这样的存储库中:http://www.rantdriven.com/post/2009/09/01/Using-the-Repository-Pattern-with-the-Command-and-DataMapper-Patterns.aspx和Repository and Data Mapper pattern,还是将它们用作存储库的替代品?我发现的所有示例似乎都使用数据映射器将DataReader对象映射到域对象列表.我想将Persistent对象映射到Domain对象.
原始问题
在阅读如下文章后,我试图构建一个与数据模型完全隔离的域模型:
http://blog.sapiensworks.com/post/2012/04/07/Just-Stop-It!-The-Domain-Model-Is-Not-The-Persistence-Model.aspx.目前我们只有6个人在使用此系统,但是将来可能会增加到9.但是,我开始认为这不是正确的方法.我在这里阅读了很多问题,这些问题似乎是在告诉我将ORM直接映射到域模型.
我最近问了一个问题:https://softwareengineering.stackexchange.com/questions/365643/should-the-data-model-be-identical-to-the-domain-model-for-mapping-purposes.其中一个回答者说:“我认为两者之间的映射应该在(面向持久性的)存储库中”.您如何进行此映射?我不认为应该在存储库中使用AutoMapper,原因是在这里说明的原因:Repository pattern and mapping between domain models and Entity Framework和此处:http://enterprisecraftsmanship.com/2016/02/08/specification-pattern-c-implementation/,即我不能简单地在存储库中这样做:
public Customer getId()
{
CustomerData customerData = customerRepository.getById(id);
return Mapper.Map<CustomerDomain>(customerData);
}
我不能这样做,因为将不考虑域对象的不变性.如何从存储库返回域对象.我是否将工厂注入存储库,该存储库将从数据模型获取参数并返回域模型?这是否是正确的方法,还是存在将数据对象映射到域对象的另一种模式?
解决方法:
根据Evans的定义快速查看存储库
REPOSITORIES (provide) the means of finding and retrieving persistent objects while encapsulating the immense infrastructure involved.
(REPOSITORIES) provide the illusion of an in memory collection…
因此,API接口通常应以特定领域的词汇表表达;除了API所表达的内容外,应用程序层和域模型都不需要知道任何细节.
通常,庞大的基础设施意味着一个与领域无关的持久性设备.我们不保留域对象,而保留字节.在某些设备上,我们与字节表示紧密合作-考虑将数据流传输到文件或从文件流传输.在其他情况下,设备提供这些字节的抽象-RDBMS为我们提供了一个API,该API可以理解表中的行,并封装有关字节排列方式的详细信息.
这意味着在某个地方,我们需要从领域不可知的表示转换为领域特定的表示,反之亦然.
通常,这些采取功能的形式.
toDomainModel: JsonDocument -> DomainModel
toJson: DomainModel -> JsonDocument
这些功能通常由存储库实现定义和调用-它们是Evans描述的庞大基础结构的一部分.
I cannot do this because the invariants of the domain object will not be considered.
这里有两种可能.
当然,一种方法是获得一个更智能的映射器.
第二种可能性是将模型的未验证表示建模为与已验证表示不同的事物.
例子:考虑一个Money的模型,它需要一个Amount和一个CurrencyCode;并且模型的语义要求Amount为正数,CurrencyCode为固定令牌集合中的条目.具有UnvalidatedMoney类型,没有语义限制以及将UnvalidatedMoney转换为Money(强制不变)的函数没有什么问题.
这类似于Scott Wlaschin所描述的建模经过验证的电子邮件地址的内容.
注意,这并不一定是不适当的负担.如果您对某些领域概念(如金钱)具有不变性,那么在将来自世界的新输入传递给模型时,您可能已经需要进行验证.因此,工作主要是关于使验证元素可重复使用.
第三种可能性是研究Builder模式.从一个角度来看,持久对象是模型过去编写的消息,以便将来可以读取.因此,通常情况下,查看常见的消息传递模式很有用.
在这种方法中,我们将加载构建器的一个实例(由工厂为我们创建,由域模型实现),该实例具有一个API,允许存储库将与域无关的数据传递到域模型.同样,由域模型提供的消息生成器知道域不变式并可以对其进行验证.
All the validation for the domain object is done in the constructor. Should I just inject a factory into the repository?
那应该没问题.您需要将耦合保持尽可能小(您可以管理)(考虑接口),并且您需要考虑以下事实:工厂现已成为模型的公共API的一部分(考虑如何更改工厂)使其保持向后兼容).
标签:domain-driven-design,c,design-patterns 来源: https://codeday.me/bug/20191025/1928119.html