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("[email protected]", ...);
或者您可以稍微更改事件發布的設計:
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(...);
我知道這種方法不使用彈簧注入,但它比將發布者傳遞給每個聚合要簡單得多,而且測試起來也不難。
添加回答
舉報