简体   繁体   English

域驱动设计中值或实体类型的存储库

[英]Repository for value or entity types in Domain Driven Design

I'm reading about Repositories in Domain Driven Design and the Microsoft patterns for micro-service architecture and they both agree that I should have one Repository per Aggregate Root. 我正在阅读有关域驱动设计中的存储库和Microsoft微服务体系结构模式的信息,他们都同意我每个聚合根都应该有一个存储库。 I generally agree with this, however I have a naming problem. 我通常对此表示同意,但是我有一个命名问题。

Aggregate is to Repository as... 聚集到存储库为...

Entity is to ??? 实体是???

Value is to ??? 值是???

In my specific scenario I have a Repository for a Product object in the context of a marketing website. 在我的特定情况下,我在营销网站的上下文中有一个Product对象的存储库。

Product is an Aggregate of the ProductInfo marketing information entity (Aggregate Root), List of ProductSpecs and ShippingInfo entities, along with a listing of RelatedProduct value references to other bounded contexts. 产品是ProductInfo市场信息实体(Aggregate Root),ProductSpecs列表和ShippingInfo实体的集合,以及对其他有界上下文的RelatedProduct值引用的列表。

Now in my Repository I have to pull together data from different Entities and value objects to make the aggregate root. 现在,在我的存储库中,我必须将来自不同实体和值对象的数据汇总在一起以形成聚合根。

I get the ProductInfo(root), and RelatedProducts(value) from a CMS. 我从CMS获得了ProductInfo(根)和RelatedProducts(值)。 The ProductSpecs(entity) and ShippingInformation(entity) come from rest apis (microservices that are handling other bounded contexts). ProductSpecs(entity)和ShippingInformation(entity)来自rest api(正在处理其他有界上下文的微服务)。

In my first attempt I created repositories/interfaces/domain pocos for all the Entities, then had the UI layer map them to viewmodels for display. 在我的第一次尝试中,我为所有实体创建了存储库/接口/域pocos,然后让UI层将它们映射到视图模型以进行显示。 Essentially making an Aggregate per Entity, however the Entities are shaped like Data Access Objects (because at this point they are), and those concerns are leaking into my domain. 本质上每个实体都创建一个聚合,但是实体的形状像数据访问对象(因为此时它们是实体),并且这些担忧正在泄漏到我的域中。 If and when we depreciate the Shipping Api and migrate that into the CMS I'll have to delete and update the repositories/interfaces then go update everything in the UI layer that touches those all because I changed the location of where I was storing something. 如果并且当我们贬低Shipping Api并将其迁移到CMS时,我将不得不删除和更新存储库/接口,然后去更新UI层中涉及到所有这些的所有内容,因为我更改了存储内容的位置。

My current attempt is to make the Aggregate a bit larger to better represent how the system is using the object rather than how it's stored, but I feel like I'm getting stuck on what to name the classes that supply the entities and values and how to architect it. 我目前的尝试是使Aggregate更大一些,以更好地表示系统如何使用对象而不是对象的存储方式,但是我感觉自己陷入了如何命名提供实体和值的类以及如何命名的问题。设计它。

I want my CMS, and Api query logic in separate projects/dlls so they can be reused, I want a repository that combines the data access objects to create aggregates. 我希望将CMS和Api查询逻辑放在单独的项目/ dll中,以便可以重用它们,我希望将数据访问对象结合在一起以创建聚合的存储库。 What do I call the classes in the CMS and Api query projects? 我在CMS和Api查询项目中如何称呼这些类? Is there a name for a pattern that I should be using? 我应该使用的模式有名称吗?

The domain driven design concepts are all about the domain model and that it should be totally independent of used technologies. 领域驱动的设计概念全都与领域模型有关,并且应该完全独立于所使用的技术。 You can achieve this by letting your domain defining business driven interfaces with expected behavior. 您可以通过让域定义具有预期行为的业务驱动接口来实现此目的。 Your infrastructure then implements these interfaces with suitable technologies. 然后,您的基础架构将使用合适的技术来实现这些接口。 You can find more about this strategy when searching for the inversion of control principle. 搜索控制原理的逆转时,可以找到有关此策略的更多信息。

The repository pattern of Eric Evans in his DDD book is a good example for this strategy. 埃里克·埃文斯(Eric Evans)在DDD书中的存储库模式就是这种策略的一个很好的例子。 I can only guess that he introduced the repository pattern instead of the more generic inversion of control principle, because it is the most common case of using technology for persisting objects. 我只能猜测,他引入了存储库模式,而不是采用更为通用的控制原理反转,因为这是使用技术来持久化对象的最常见情况。

For me the repository is also the factory for a very important model types, the aggregates. 对我来说,存储库也是非常重要的模型类型(聚合)的工厂。 For this reason you should use them as described by your references taken from Microsoft. 因此,您应该按照Microsoft的参考资料中的说明使用它们。 This includes that your repository is capable of giving you the root aggregate as a whole consistent unit including embedded entities and value objects. 这包括您的存储库能够为您提供根聚合,作为一个整体一致的单元,包括嵌入式实体和值对象。

This is the only way your root aggregates can take their responsibility to always managing a consistent state within their boundaries. 这是您的根聚合可以承担始终在其边界内始终保持一致状态的责任的唯一方法。 Eric talks here of holding invariants. 埃里克在这里谈到保持不变性。

So far so good. 到现在为止还挺好。 Now you come to an ugly part. 现在,您进入了一个丑陋的部分。 If you model your aggregates as they suit your domain best, you will have to solve the problem of mapping the domain model to a specific database model/technology. 如果您按照最适合您的域的方式对聚合进行建模,则必须解决将域模型映射到特定数据库模型/技术的问题。 This is called the object relational impedance mismatch. 这称为对象关系阻抗失配。 Object relational mappers (ORMs) like JPA, Hibernate, etc. should solve this for you, but the problem stays that this can be a cumbersome and tricky part. 对象关系映射器(ORM)(如JPA,Hibernate等)应为您解决此问题,但是问题仍然在于,这可能是一个麻烦且棘手的部分。

Nonetheless you should hide all this ugly things in the repository implementation. 但是,您应该在存储库实现中隐藏所有这些难看的东西。 You will need their DAOs, JEE entities, entity managers. 您将需要他们的DAO,JEE实体,实体管理器。 Whatever. 随你。 But you never expose them beyond the repository interface. 但是,您永远不会在存储库界面之外公开它们。

Last I will cover your GUI topic. 最后,我将介绍您的GUI主题。 Who uses the domain with all it's fine granular model elements? 谁将领域与所有精细的模型元素一起使用? Normally only the application layer that formulates commands from user input and delivers views for user output. 通常,只有应用程序层可以根据用户输入来制定命令,并为用户输出提供视图。 You can think of the application layer as the translator between GUI and the domain. 您可以将应用程序层视为GUI和域之间的转换器。 For this reason you expose some kind of slowly changing and long term stable model to the GUI and can go in fast pace changes in your model. 因此,您需要向GUI提供某种缓慢变化且长期稳定的模型,并且可以快速进行模型更改。

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM