Spa*_*vić 5 java spring domain-driven-design
我正在尝试在我的项目中实现域驱动设计。这是我的基Aggregate类:
public abstract class UUIDAggregate {
private final DomainEventPublisher domainEventPublisher;
protected void publish(DomainEvent domainEvent) {
domainEventPublisher.publish(domainEvent);
}
}
Run Code Online (Sandbox Code Playgroud)
假设我们有UserAccount聚合:
public class UserAccount extends UUIDAggregate {
private String email;
private String username;
private String password;
private String firstName;
private String lastName;
public void update() {
publish(new DomainEventImpl());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的DomainEventPublisher:
public interface DomainEventPublisher {
void publish(DomainEvent event);
}
Run Code Online (Sandbox Code Playgroud)
这是DomainEventPublisherImpl:
@Component
public class DomainEventPublisherImpl implements DomainEventPublisher{
@Autowired
private ApplicationEventPublisher publisher;
public void publish(DomainEvent event){
publisher.publishEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这似乎是一个好主意,域与实现分离,但这不起作用。DomainEventPublisher不可能是Autowired因为UUIDAggregate不是@Component或@Bean。一种解决方案是在那里创建DomainService和发布事件,但这似乎将域泄漏到域服务,如果我这样做,我将进入贫血模型。此外,我可以做的是将DomainEventPublisher参数作为参数传递给每个聚合,但这似乎也不是一个好主意。
一个想法是为域对象建立一个工厂:
@Component
class UserAccountFactoryImpl implements UserAccountFactory {
@Autowired
private DomainEventPublisher publisher;
@Override
public UserAccount newUserAccount(String email, String username, ...) {
return new UserAccount(email, username, ..., publisher);
}
}
Run Code Online (Sandbox Code Playgroud)
那么创建域对象的代码是“无发布者的”:
UserAccount userAccount = factory.newUserAccount("john@example.com", ...);
Run Code Online (Sandbox Code Playgroud)
或者您可以稍微更改事件发布的设计:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这与您的建议不同:服务发布事件,但不创建事件 - 逻辑保留在域对象中。
此外,您可以更改发布者以最小化样板代码:
public interface DomainEventPublisher {
void publish(UUIDAggregate aggregate);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2772 次 |
| 最近记录: |