假设我有以下简单的域模型设置:
class Event { ... }
class PlannedEvent { Event event; DateTime date; .. }
我想把事件描述为尽可能描述,我会把它写成
class Event {
public void plan(DateTime date) {
// Can I create and Store a PlannedEvent here ?
// in other words access a Repository
}
我添加了计划方法,因为在无处不在的语言中,您计划一个事件,这将在未来的某个地方产生计划事件。因此将计划方法放在Event类中是很自然的。
我一直都知道你不能在域对象中使用repostories我能理解为什么,但是我怎么解决上面的问题呢?
这是域事件发挥作用的地方吗?
class Event {
public void plan(DateTime date) {
DomainEventPublisher
.instance()
.publish(new PlannedEventCreated(this, date)));
}
域事件将确保将(通过存储库)创建和存储PlannedEvent?
答案 0 :(得分:1)
可以想象Event和PlannedEvent都是聚合根吗?我怀疑Event应该知道关于PlannedEvent的任何信息,当然不是如何构建一个 - 这超出了它的范围。埃文斯说到工厂:
当创建对象或整个AGGREGATE变得复杂或显示太多内部结构时,FACTORIES提供封装。
也许您使用聚合工厂为事件构建PlannedEvent。为了将这两者分离,我宁愿通过PlannedEvent中的一些唯一Event-ID而不是直接对象引用来引用Event。您可以使用此ID通过其存储库查找事件。
答案 1 :(得分:1)
您可以将Event用作PlannedEvent的工厂:
class Event {
public PlannedEvent plan(DateTime date) {
return new PlannedEvent(getId(), date,...);
}
}
class PlanningService {//This is an application service
public void plan(String eventId) {
Event event = eventRepository.findBy(eventId);
PlannedEvent pe = event.plan(clock.now());
plannedEventRepository.store(pe);
}
}
当然,如果事情变得复杂,最好有一个PlannedEventFactory。
您不会将EventnedEvent存储在Event中。让域模型(或额外的工厂)提供某种工厂方法来创建PlannedEvent并让存储库完成工作。