正确设计骨料根
我在设计聚合根时遇到一些问题。这是我在脑海中的看法:)
Store (the aggregate root)
-> Sales - A store create a sale every day
-> Zones - A store is divided into zones
-> Styles - A zone has x number of styles
--> Colors - A style has x number of colors
etc..
现在基于此,我的聚合根将是商店。但是,如果我现在围绕它创建一个存储库,它会看起来像这样吗?
public class StoreRepository()
{
Store GetById() {...}
StoreZone GetZone() {...}
List<StoreZoneStyle> GetStylesByZone() {...}
List<Color> GetColorsByStyle() {...}
}
这是继续下去的好方法吗? 不用说我是 DDD 新手。
I have some problems designing the aggregate root. Here is how I see it in my mind :)
Store (the aggregate root)
-> Sales - A store create a sale every day
-> Zones - A store is divided into zones
-> Styles - A zone has x number of styles
--> Colors - A style has x number of colors
etc..
Now based on this my aggregate root would be the store. However if I were now to create a Repository around that, would it look something like this?
public class StoreRepository()
{
Store GetById() {...}
StoreZone GetZone() {...}
List<StoreZoneStyle> GetStylesByZone() {...}
List<Color> GetColorsByStyle() {...}
}
Is that a good way to continue?
Needless to say that I am new to DDD.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您需要将聚合边界和实体视为不仅仅是层次结构。您很可能会拥有比这更丰富的模型。
判断聚合是否正确的第一种方法是,您可以查看其中的每个实体并询问“是否需要直接访问?”如果您回答“是”,则该实体可能不是聚合的一部分。
如果不了解有关您的域的更多信息,我可能会认为 Store 确实是一个聚合。另一方面,销售则更为复杂。是的,销售发生在商店中,但您是否需要独立使用销售?如果您在与商店合作的范围之外需要它们,那么销售额可能不在该总量范围内。
我想象样式和颜色都是不可变且可重复的,因此在这种情况下它们可能是值对象。区域是商店独有的还是各有不同?
就我个人而言,我发现在纸上(或白板)上识别域中的所有项目很有价值。我将与利益相关者一起经历一个发现阶段,然后让他们出去。然后,在对话中使用这些词作为引导语,尝试理解它们之间的关系。如果您足够充分地采访利益相关者,他/她给出的描述实际上将定义您正在寻找的大部分内容。
不是说死马当活马医,但埃文斯的书绝对值得一读。虽然有点干,但是很有洞察力。要快速入门,您可以阅读 InfoQ 上的免费书籍,基本上是埃文斯书的摘要。
I think you need to look at the aggregate boundaries and the entities as something more than just a hierarchy. Chances are, you will have a richer model than that.
The first way to tell if your aggregate is right, is that you can look at each of the entities within it and ask "Does this need to be directly accessed?" If you answer yes, then that entity is likely not a part of the aggregate.
Without knowing more about your domain, I might assume that Store is indeed an aggregate. Sales, on the other hand, are more complex. Yes, sales occur in a store, but do you have a need to look use a sale independently? If you need them outside of the scope of just working with a store, Sales is probably outside of that aggregate.
I am imagining that both Styles and Colors are immutable and repeatable, so they would likely be Value Objects in this case. Are Zones unique to a store, or do they vary?
Personally, I find value in identifying all of the items in the domain on paper (or whiteboard). I will go through a discovery phase with the stakeholder and just get them out there. Then, use these words as leaders in the conversation, trying to understand how they relate. If you interview the stakeholder well enough, the description he/she gives will actually define most of what you are looking for.
Not to beat a dead horse, but the Evans book is definitely worth getting/reading. It is a little dry, but very insightful. For a quick jumpstart, you can read the free book up on InfoQ that is basically a summary of the Evans book.
聚合根是事务、分布和并发的一致性边界 (埃里克·埃文斯 (Eric Evans) 通过 Gojko Adzic)。
当两个人修改同一个Store中的不同Zone时,这是否会导致并发冲突?如果不是,那么区域可能应该是与商店分开的自己的聚合根。
Aggregate Roots are consistency boundaries for transactions, distributions and concurrency (Eric Evans via Gojko Adzic).
When two people modify different Zones in the same Store, should this cause a concurrency conflict? If not, then perhaps Zones should be their own Aggregate Root separate from Stores.
看来“Store”不是聚合根,因为您不想在“Store”对象后面隐藏“Zones”、“Sales”等的所有功能。这样“Store”对象可能会非常臃肿。
“商店”、“区域”和“销售”可以有自己的存储库。
It seems that "Store" isn't aggregate root because you don't want to hide all functionality for "Zones", "Sales" etc behind "Store" object. That way "Store" object might be very bloated.
"Store", "Zone" and "Sale" could have it's own repository.