我读过从聚合根访问存储库被视为不良做法。 如果是,请考虑以下示例:
class User {
private String username;
public void changeUsername(String newUsrname) {
// How will I persist username to database if I don't have access to repository from aggregate root?
...
}
}
如果我无权访问存储库,我将如何将用户名持久保存到数据库 来自聚合根?
我这样看:
class User {
private String username;
private UserRepository userRepository;
public User(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void changeUserName(String newUsername) {
this.username = newUserName;
userRepository.save(this);
}
}
或者我在DDD概念中遗漏了什么?
答案 0 :(得分:7)
如果我无法从聚合根访问存储库,我将如何将用户名持久保存到数据库?
当前的做法通常处理应用程序组件中的I / O,而不是域模型中的I / O.
Application {
void when(ChangeUserName command) {
User user = this.userRepository.getUserById(command.userId);
user.changeName(command.name);
this.userRepository.save(user);
}
}
推荐阅读:Vladimir Khorikov关于域模型隔离。
答案 1 :(得分:0)
只是为了扩展@VoiceOfUnreason给出的答案(这是完全正确的),这里有一个快速解释为什么不建议通过构造函数将存储库注入Aggregate Roots:
存储库应该依赖于它返回的对象,而不是相反。这样做的原因是你的“域对象”(以后更多)可以存在(并且应该是可测试的)而不加载或保存(即,依赖于存储库)。
基本上你的设计说,为了拥有一个用户,你需要提供一个MySQL / Mongo / XXX实例连接,这是一个基础设施细节。您的域名不应该知道它是如何持久化的。您的域名了解行为,不变量,业务规则等。
这些概念只是帮助您创建更易于维护的代码,并帮助您应用SRP(单一责任原则)等最佳实践。