DDD:从聚合根访问存储库被视为不良做法?

时间:2016-10-06 12:32:43

标签: java domain-driven-design ddd-repositories aggregateroot

我读过从聚合根访问存储库被视为不良做法。 如果是,请考虑以下示例:

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概念中遗漏了什么?

2 个答案:

答案 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(单一责任原则)等最佳实践。