2 回答
TA贡献1911条经验 获得超7个赞
一个想法是为域对象建立一个工厂:
@Component
class UserAccountFactoryImpl implements UserAccountFactory {
@Autowired
private DomainEventPublisher publisher;
@Override
public UserAccount newUserAccount(String email, String username, ...) {
return new UserAccount(email, username, ..., publisher);
}
}
那么创建域对象的代码是“无发布者的”:
UserAccount userAccount = factory.newUserAccount("john@example.com", ...);
或者您可以稍微更改事件发布的设计:
public abstract class UUIDAggregate {
private final List<DomainEvent> domainEvents = new ArrayList<>();
protected void publish(DomainEvent domainEvent) {
domainEvents.add(domainEvent);
}
public List<DomainEvent> domainEvents() {
return Collections.unmodifiableList(domainEvents);
}
}
@Component
class UserAccountServiceImpl implements UserAccountService {
@Autowired
private DomainEventPublisher publisher;
@Override
public void updateUserAccount(UserAccount userAccount) {
userAccount.update();
userAccount.domainEvents().forEach(publisher::publishEvent);
}
}
这与您的建议不同:服务发布事件,但不创建事件 - 逻辑保留在域对象中。
此外,您可以更改发布者以最小化样板代码:
public interface DomainEventPublisher {
void publish(UUIDAggregate aggregate);
}
TA贡献1804条经验 获得超7个赞
Vaughn Vernon 在他的《IDDD》一书中就这样使用了单例:
DomainEventPublisher.instance().register(...); DomainEventPublisher.instance().publish(...);
我知道这种方法不使用弹簧注入,但它比将发布者传递给每个聚合要简单得多,而且测试起来也不难。
添加回答
举报