简体   繁体   English

DDD聚合根

[英]DDD aggregate roots

I have question regarding and bounded contexts. 我对和有界上下文有疑问。

Suppose there are two bounded contexts. 假设有两个有界上下文。 In the first one the aggregate root is Customer who is able to publish an advertisement on a webpage. 在第一个中,总根是能够在网页上发布广告的客户。 I suppose that falls in his behavior, in turn he has a method of PublishAdvertisement(). 我想这取决于他的行为,反过来,他又拥有PublishAdvertisement()方法。 But the second bounded context has Advertisement as aggregate. 但是第二个有界上下文将广告作为聚合。 That imposes that Advertisement has a Customer property, due to its nature of belonging to a Customer. 由于广告属于客户的性质,因此这意味着广告具有客户属性。

Both Customer and Advertisement are unique in the system and database. 客户和广告在系统和数据库中都是唯一的。

My question is: Is it advisable to delegate the creation of Advertisement from Customer to a factory or dependency injection? 我的问题是:建议将广告的创建从客户委托给工厂或依赖项注入吗?

Edit: 编辑:

I thank you for your answers and apologize for the lack of info. 感谢您的回答,对于缺少信息,我们深表歉意。

Dependency injection: 依赖注入:

I was wondering what is the best manner to resolve a given situation. 我想知道解决给定情况的最佳方法是什么。 The company has a Stock of Advert templates, if a template is in stock its good for use, if it's not, then it's rented to someone. 该公司有一个“广告库存”模板,如果模板中有可用的模板,如果没有,则将其出租给某人。 The company has a plan on having more Stocks. 该公司有计划增加股票。 If a Customer wants to make an advert in these templates he chooses a template and if its in stock all is good to go. 如果客户想在这些模板中做广告,他会选择一个模板,并且如果有现货,一切都很好。 Reading this as it is I assumed that there should be a service(domain) CheckAvailability(template), due to the nature of the service it does not fit in a specific aggregate because it uses several aggregates with validations and queries the database. 读取此内容是因为我假定应该有一个服务(域)CheckAvailability(模板),由于该服务的性质,它不适合特定的聚合,因为它使用多个聚合进行验证并查询数据库。 In future when there would be more Stocks(some rented from other companies, maybe someone else's database), I was planing on using dependency injection to add these Stocks to the service without changing the implementation. 将来会有更多的库存(一些是从其他公司租来的,也许是其他人的数据库租用的)时,我计划使用依赖项注入将这些库存添加到服务中,而无需更改实现。 Question is , does this seem as a good idea? 问题是,这似乎是个好主意吗?

Bounded contexts: 有界上下文:

In regards to bounded contexts and database. 关于有限的上下文和数据库。 Yes, there is one database object and two contexts that use the same database object. 是的,有一个数据库对象和两个使用同一数据库对象的上下文。 Order has a reference to Customer, due to belonging to a Customer, looks something like this 订单具有对客户的引用,由于属于客户,因此如下所示

Order() Customer customer(get; private set;) Order()客户客户(获取;私有集;)

///other properties and methods ///其他属性和方法

I would appreciate any additional information via link, video, book in terms of implications of having 2 contexts like these (Customer->Order___1:M) relate to the same database. 我希望通过链接,视频,书本获得的任何其他信息,对具有这样2个上下文(客户->订单___ 1:M)的同一个数据库都具有影响。 Thank you. 谢谢。

Both Customer and Advertisement are unique in the system and database. 客户和广告在系统和数据库中都是唯一的。

If that is the case, then having these concepts in two bounded contexts that use the same DB objects is a problem! 如果是这样,那么在使用相同数据库对象的两个有界上下文中拥有这些概念将是一个问题! The separation between two bounded contexts is a strong one, so they shouldn't communicate by changing the same DB object. 两个有界上下文之间的分隔是很强的,因此它们不应通过更改同一数据库对象来进行通信。

So I think you have some major design issues there. 所以我认为您那里存在一些主要的设计问题。 Try to fix them first by creating a model that corresponds to the real-world problem, discuss it with your domain experts. 首先尝试通过创建与实际问题相对应的模型来修复它们,并与您的领域专家讨论。

And now to answer your main question: 现在回答您的主要问题:

Creating entities through factories is a good idea. 通过工厂创建实体是一个好主意。 The factory hides the (potentially complex) mechanism to create an entity and provide it with the required services. 工厂隐藏了(可能很复杂的)机制来创建实体并为其提供所需的服务。 The factory receives these services through DI in the first place, and can forward them to the entity during instantiation. 工厂首先通过DI接收这些服务,并可以在实例化时将其转发给实体。

Absolutely. 绝对。

One thing is associating domain objects and another thing is working with them. 一件事是关联域对象,另一件事是使用它们。 An ad has some associated customer , and the customer and ad must be created in their respective domain layers ( ie repository and service at least... ). 广告具有一些关联的客户 ,并且客户广告必须在其各自的域层中创建( 即,至少要有存储库和服务... )。

This is separating concerns in the right way, since you don't want customers to be created where ads are also created and vice versa. 由于您不希望在创建广告的地方创建客户,反之亦然,因此可以以正确的方式将关注点分开。

I guess you already know the single responsibility principle . 我想您已经知道单一责任原则

What are the customer related invariants enforced by Customer.PublishAdvertisement() ? Customer.PublishAdvertisement()强制执行哪些与客户相关的不变式?

  • If there aren't any, you'll be better off moving that method to the Advertisement aggregate root in the other BC, perhaps making it a constructor or to an AdvertisementFactory if the construction logic is complex. 如果没有任何方法,最好将该方法移至另一个BC中的Advertisement聚合根,如果构造逻辑很复杂,则可以将其构造为构造器,或者移至AdvertisementFactory Just because the physical world user who creates an ad is a Customer doesn't automatically imply that their aggregate root should have that method. 仅仅因为创建广告的实际用户是客户,并不能自动暗示他们的总根应具有该方法。 The ad creation process can stay in the Advertisement BC, with an Advertisement application service as the entry point. 广告创建过程可以停留在Advertisement BC中,以Advertisement应用程序服务为切入点。

  • If there are, then Customer could emit an AdvertisementPublished event that the Advertisement BC subscribes to. 如果存在,则客户可以发出AdvertisementBC订阅的AdvertisementPublished事件。 You should be aware though that if you follow the "aggregate as consistency boundary" good practice, Customer can't be immediately consistent with Advertisement which means that there can be a delay and inconsistencies can be introduced between when the event is emitted and when the Advertisement is persisted and thus visible to other clients. 不过,您应该知道,如果遵循“汇总为一致性边界”的良好做法,则客户将不会立即与Advertisement保持一致,这意味着可能会有所延迟,并且在事件发生的时间与事件之间的时间之间可能会引入不一致。 Advertisement是持久的,因此对其他客户可见。

    It is usually not an issue when you are creating a new AR, but keep in mind that the state of the Customer that checked the invariants and decided to create the Advertisement can change and the invariants be violated in the mean time, before Advertisement is persisted. 它通常不是当你创建一个新的AR的问题,但要记住的是,状态Customer是检查不变量,并决定建立的Advertisement 可以改变与不变的平均时间被侵犯,之前Advertisement的坚持。

    Obviously, given that the 2 BCs share a common database (which is probably not a good idea as @theDmi pointed out), you could decide to break that rule and make your transaction span across the 2 aggregates. 显然,鉴于两个BC共享一个公共数据库(@theDmi指出,这可能不是一个好主意),您可以决定打破该规则,并使您的交易跨两个聚合。 Not necessarily that bad if you just persist a new Advertisement and not modify one that can potentially be accessed concurrently. 如果您仅保留一个新的广告并且不修改可以同时访问的广告,那并不一定那么糟糕。

As far as dependency injection, I can't see the connection here -- what is the dependency to be injected ? 至于依赖注入,我在这里看不到连接-要注入的依赖是什么?

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

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