举个例子。 主管域类公开了一种方法 GetUnderlings(DateTime from,DateTime to),它将返回指定主管在给定时间段内监督的所有人员。
这个方法应该出于愉快的语义原因。但是应该去其他地方获得DDD纯度。那是因为我假设要实现方法,需要使用一个Repository,这似乎是错误的嵌入域实体。在这种情况下,该方法应该在存储库或服务上 - GetUnderlings(主管主管,DateTime from,DateTime to)
其他人如何处理这种情况?
编辑:我认为这些力量可以这样描述:根据OO负责人的说法,我希望我的实体的公共接口公开一组丰富的面向业务的功能。但是根据DDD实现原理,这些方法的实现可能最好位于其他地方。例如,在服务中。如何解决这种明显的冲突?我能看到的方式是:
答案 0 :(得分:2)
如果Supervisor
是Aggregate Root
,则从Underlings
返回Supervisor
列表是有效的,但只有 READONLY 集合,因为Underlings
由Supervisor
修改shold以将域规则和不变量应用于修改操作。 (不仅在DDD中的基本规则,只是很好的OOP设计)
Underlings
似乎是历史entity
。在大多数情况下(我没有足够的上下文信息来确认您的情况)历史记录entities
不是aggregate roots
而仅 aggregate roots
拥有存储库。
请注意,如果Undelings
的检索用于UI
(不应用带有规则和不变量的操作),则无需关心aggregate roots
,{{1等等,因为您应该应用CQRS并使用视图服务来检索纯数据(第一范式,而不是entities
)以向用户显示。当用户aggregate roots
触发某个操作时,您需要检查规则(这意味着应用DDD);您从UI
检索Supervisor
,检查Repository
(请记住,只读集合)以接受决定,应用操作并保存更改。
答案 1 :(得分:0)
常用方法是将所有Supervisor
的{{1}}公开为只读集合。如果您需要实现按日期范围过滤它们的方法,只需将此方法添加到Underlings
类Supervisor
,一切正常。
如果常见方法不起作用,因为GetUnderlings(DateTime from, DateTime to)
有很多Supervisor
,或者检索所有这些Underlings
或者是非常耗时的。 ..有一种解决方法 - Martin Fowler的“Separated Interface”(PoEAA)模式。
您可以在域模型中的特定日期范围内定义返回Underlings
的组件接口,但在另一层(例如数据访问层)中实现它。
在这种情况下,您的域名实体没有提及服务,也没有公开任何“Underlings”。所有需要获得“Underlings”服务并且将“Supervisor”实例传递到方法和日期范围的客户。
答案 2 :(得分:0)
如果主管属于主管总会,主管应该有一系列基础。
喜欢
class Supervisor {
private Collection<Underlying> underlyings;
}
然后GetUnderlings(DateTime from,DateTime to)正在过滤联系人。这很好。
但如果属于主管的基础太多,则此解决方案对性能不友好。在这种情况下,我想使用make underlying一个聚合根并使用它的Repository来检索结果,如:
interface UnderlyingRepository {
Collection<Underlying> GetUnderlings(Guid supervisorId, DateTime from, DateTime to);
}
客户端(可能是MVC控制器)直接调用存储库。那么问题是如何保护addUnderlying的不变量,这些变量曾经受到Supervisor聚合的保护。 您可以使用DomainService或DomainEvents。
上述解决方案基于传统的DDD架构模型。就像@jlvaquero所说,你可以改用CQRS。