Одной из идей было бы создать фабрику для доменных объектов:
@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);
}