2 回答

TA貢獻1911條經(jīng)驗 獲得超7個贊
一個想法是為域?qū)ο蠼⒁粋€工廠:
@Component
class UserAccountFactoryImpl implements UserAccountFactory {
@Autowired
private DomainEventPublisher publisher;
@Override
public UserAccount newUserAccount(String email, String username, ...) {
return new UserAccount(email, username, ..., publisher);
}
}
那么創(chuàng)建域?qū)ο蟮拇a是“無發(fā)布者的”:
UserAccount userAccount = factory.newUserAccount("john@example.com", ...);
或者您可以稍微更改事件發(fā)布的設(shè)計:
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);
}
}
這與您的建議不同:服務(wù)發(fā)布事件,但不創(chuàng)建事件 - 邏輯保留在域?qū)ο笾小?/p>
此外,您可以更改發(fā)布者以最小化樣板代碼:
public interface DomainEventPublisher {
void publish(UUIDAggregate aggregate);
}

TA貢獻1804條經(jīng)驗 獲得超7個贊
Vaughn Vernon 在他的《IDDD》一書中就這樣使用了單例:
DomainEventPublisher.instance().register(...); DomainEventPublisher.instance().publish(...);
我知道這種方法不使用彈簧注入,但它比將發(fā)布者傳遞給每個聚合要簡單得多,而且測試起來也不難。
添加回答
舉報