You could model that with a single aggregate, Product (root) + Offer (object value or entity). The name ProductOffer should be a good hint that this object should not be a root "aggregate" and is aggrgated to the Product. Also note that single entities are not aggregate, they are entities. The term aggregate describes situations with multiple object.
The seller can use Product.MakeOffer() to make an offer. This will check there is no existing pending offer from that buyer in the Product.Offers collection.
The buyer can use Offer.Accept() to accept an offer. Since the offer is a child item in the aggregate, you need to return the whole aggregate from the repository, allowing you to compare the Offer.Quantity to the Product.InStock for instance.
Addendum:
For rejection, you don't need that complexity. Aggregates MAY overlap into a polysemic model. You could have a separate Offer entity (not the same used by the Product+Offer aggregate) used for the offer rejection use case. This could save some database read performance.
Don’t forget about simplicity. Simplify everything you can. The fewer things you have, the easier it’s to control them. My friend from https://transformagency.com/ has the same philosophy, which I really like. What to make things more complicated? When you can make them more simple. Minimalism is a new must. As you can see, it’s everywhere. We often notice it in design, food, and general lifestyle. So, I think you’ve solved your issue successfully. If any problems happen, let us know.
发布评论
评论(2)
你过度设计了你的问题。
回到您的用例:
您可以使用单个聚合(产品(根)+报价(对象值或实体))对其进行建模。名称
ProductOffer
应该很好地暗示该对象不应该是根“聚合”,而是聚合到 Product。另请注意,单个实体不是聚合的,它们是实体。术语“聚合”描述了具有多个对象的情况。卖家可以使用
Product.MakeOffer()
进行报价。这将检查 Product.Offers 集合中是否没有来自该买家的现有待处理报价。买家可以使用
Offer.Accept()
接受报价。由于报价是聚合中的子项,因此您需要从存储库返回整个聚合,以便您可以将 Offer.Quantity 与 Product.InStock 进行比较。附录:
对于拒绝,您不需要那么复杂。聚合可能会重叠成多义模型。您可以有一个单独的要约实体(与产品+要约聚合使用的实体不同)用于要约拒绝用例。这可以节省一些数据库读取性能。
You are over-engineering your problem.
Get back to your use cases:
You could model that with a single aggregate, Product (root) + Offer (object value or entity). The name
ProductOffer
should be a good hint that this object should not be a root "aggregate" and is aggrgated to the Product. Also note that single entities are not aggregate, they are entities. The term aggregate describes situations with multiple object.The seller can use
Product.MakeOffer()
to make an offer. This will check there is no existing pending offer from that buyer in the Product.Offers collection.The buyer can use
Offer.Accept()
to accept an offer. Since the offer is a child item in the aggregate, you need to return the whole aggregate from the repository, allowing you to compare the Offer.Quantity to the Product.InStock for instance.Addendum:
For rejection, you don't need that complexity. Aggregates MAY overlap into a polysemic model. You could have a separate Offer entity (not the same used by the Product+Offer aggregate) used for the offer rejection use case. This could save some database read performance.
不要忘记简单性。尽可能简化一切。你拥有的东西越少,就越容易控制它们。我来自 https://transformagency.com/ 的朋友也有同样的理念,我真的很喜欢。什么会让事情变得更复杂?当你能让它们变得更简单时。极简主义是新的必须。正如你所看到的,它无处不在。我们经常在设计、食品和一般生活方式中注意到它。所以,我认为你已经成功解决了你的问题。如果发生任何问题,请告诉我们。
Don’t forget about simplicity. Simplify everything you can. The fewer things you have, the easier it’s to control them. My friend from https://transformagency.com/ has the same philosophy, which I really like. What to make things more complicated? When you can make them more simple. Minimalism is a new must. As you can see, it’s everywhere. We often notice it in design, food, and general lifestyle. So, I think you’ve solved your issue successfully. If any problems happen, let us know.