简体   繁体   English

DDD:从聚合根访问存储库是否被认为是不好的做法?

[英]DDD: is accessing repository from aggregate root considered bad practice?

I've read that accessing repository from aggregate root considered bad practice. 我读过从聚合根访问存储库被认为是不好的做法。 If it is, than consider following example: 如果是这样,那么请考虑以下示例:

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?
     ...
   }
}

How will I persist username to database if I don't have access to repository from aggregate root? 如果无法从聚合根访问存储库,如何将用户名持久化到数据库?

I see it like this: 我看到这样的:

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); 
    }
}

Or I've missed something in DDD concepts? 还是我错过了DDD概念?

How will I persist username to database if I don't have access to repository from aggregate root? 如果无法从聚合根访问存储库,如何将用户名持久化到数据库?

Current practices normally handle I/O in the application component, rather than in the domain model. 当前的实践通常在应用程序组件而不是域模型中处理I / O。

Application {
    void when(ChangeUserName command) {
        User user = this.userRepository.getUserById(command.userId);
        user.changeName(command.name);
        this.userRepository.save(user);
    }
}

Recommended reading: Vladimir Khorikov on domain model isolation. 推荐阅读: Vladimir Khorikov关于域模型隔离。

Just to extend a little the answer given by @VoiceOfUnreason (which is totally right) here a quick explanation on why injecting repositories via constructor to Aggregate Roots is not advisable: 只是为了扩展@VoiceOfUnreason给出的答案(完全正确),这里快速解释一下为什么不建议通过构造函数将存储库注入到Aggregate Roots:

The repository should depend on the object it returns, not the other way around. 存储库应取决于它返回的对象,而不是相反。 The reason for this is that your "domain object" (more on that later) can exist (and should be testable) without being loaded or saved (that is, having a dependency on a repository). 这样做的原因是,您的“域对象”(稍后会详细介绍)可以存在(并且应该是可测试的)而无需加载或保存(即,对存储库有依赖性)。

Basically your design says that in order to have an user, you need to provide a MySQL/Mongo/XXX instance connection which is an infrastructure detail. 基本上,您的设计说要拥有一个用户,您需要提供一个MySQL / Mongo / XXX实例连接,该连接是基础结构的详细信息。 Your domain should not know anything about how it is persisted. 您的域不应该知道如何持久化。 Your domain knows about the behavior, invariants, business rules and so on. 您的域了解行为,不变式,业务规则等。

These concepts just help you to create code easier to maintain as well as help you to apply best practices such as SRP (Single Responsibility Principle). 这些概念不仅可以帮助您创建易于维护的代码,而且可以帮助您应用最佳实践,例如SRP(单一责任原则)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 就 DDD 而言,是否可以在域服务中为聚合根实体而不是聚合根存储库实现 crud 逻辑? - Can crud logic be implemented in domain service for an aggregate root entity instead of this aggregate root repository in terms of DDD? 倒铸是否被视为不良做法? - Is down casting considered bad practice? DDD:如何从Kotlin中的集成层隐藏特定的聚合根构造函数 - DDD: How to hide specific aggregate root constructors from integration layers in Kotlin 多个 HttpAsyncClient 是否被认为是一种不好的做法? - Is multiple HttpAsyncClient's considered a bad practice? 为什么通过扩展来测试类被认为是一种不好的做法? - Why is it considered a bad practice to test a class by extending it? 是否增加堆栈大小被认为是不好的做法? - Is increasing stack size considered to be a bad practice? 在fileds的setter中更新观察者被认为是不好的做法吗? - Is it considered as bad practice to update observers in fileds' setters? SwingUtilities InvokeLater- 什么被认为是不好的做法? - SwingUtilities InvokeLater- what is considered bad practice? 为什么 exception.printStackTrace() 被认为是不好的做法? - Why is exception.printStackTrace() considered bad practice? 锁定可变对象-为什么将其视为不良做法? - Locking on a mutable object - Why is it considered a bad practice?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM