存储库、服务或域对象 - 逻辑属于哪里?
采取这个简单的、人为的示例:
UserRepository.GetAllUsers(); UserRepository.GetUserById();
不可避免地,我会遇到更复杂的“查询”,例如:
//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();
我无法确定存储库的责任在哪里结束。 GetActiveUsers() 代表一个简单的“查询”。 它属于存储库吗?
涉及一些逻辑的事情怎么样,例如:
//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);
Take this simple, contrived example:
UserRepository.GetAllUsers();
UserRepository.GetUserById();
Inevitably, I will have more complex "queries", such as:
//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();
I'm having trouble determining where the responsibility of the repository ends. GetActiveUsers() represents a simple "query". Does it belong in the repository?
How about something that involves a bit of logic, such as:
//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
存储库负责对对象集进行特定于应用程序的处理。这自然涵盖查询以及设置修改(插入/删除)。
ActivateUser
对单个对象进行操作。需要检索该对象,然后对其进行修改。存储库负责从集合中检索对象;另一个类将负责调用查询并使用该对象。Repositories are responsible for the application-specific handling of sets of objects. This naturally covers queries as well as set modifications (insert/delete).
ActivateUser
operates on a single object. That object needs to be retrieved, then modified. The repository is responsible for retrieving the object from the set; another class would be responsible for invoking the query and using the object.这些都是很好的问题。能够确定应该使用哪一个取决于您的经验和您正在解决的问题。
我建议阅读一本书,例如 Fowler 的企业架构模式。在这本书中,他讨论了你提到的模式。最重要的是,他为每个模式分配了职责。例如,域逻辑可以放在服务层或域层中。每种方法都有优点和缺点。
如果我决定使用服务层,我会为该层分配处理事务和授权的角色。我喜欢保持它的“薄”并且其中没有领域逻辑。它成为我的应用程序的 API。我将所有业务逻辑与域对象一起保存。这包括对象的算法和验证。存储库检索并保留域对象。对于简单系统,这可能是数据库列和域属性之间的一对一映射。
我认为 GetAtcitveUsers 对于存储库来说是可以的。您不希望从数据库中检索所有用户并找出哪些用户在应用程序中处于活动状态,因为这会导致性能不佳。如果 ActivateUser 具有您建议的业务逻辑,那么该逻辑属于域对象。保存更改是存储库层的责任。
希望这有帮助。
These are all excellent questions to be asking. Being able to determine which of these you should use comes down to your experience and the problem you are working on.
I would suggest reading a book such as Fowler's patterns of enterprise architecture. In this book he discusses the patterns you mention. Most importantly though he assigns each pattern a responsibility. For instance domain logic can be put in either the Service or Domain layers. There are pros and cons associated with each.
If I decide to use a Service layer I assign the layer the role of handling Transactions and Authorization. I like to keep it 'thin' and have no domain logic in there. It becomes an API for my application. I keep all business logic with the domain objects. This includes algorithms and validation for the object. The repository retrieves and persists the domain objects. This may be a one to one mapping between database columns and domain properties for simple systems.
I think GetAtcitveUsers is ok for the Repository. You wouldnt want to retrieve all users from the database and figure out which ones are active in the application as this would lead to poor performance. If ActivateUser has business logic as you suggest, then that logic belongs in the domain object. Persisting the change is the responsibility of the Repository layer.
Hope this helps.
在构建 DDD 项目时,我喜欢区分两个职责:存储库和查找器。
存储库负责存储聚合根并检索它们,但仅用于命令处理。通过命令处理,我的意思是执行用户调用的任何操作。
Finder 负责出于 UI 目的查询域对象,例如网格视图和详细信息视图。
我不认为查找器是领域模型的一部分。特定的 IXxxFinder 接口位于表示层,而不是域层。 IXxxRepository 和 IXxxFinder 的实现都放置在数据访问层中,甚至可能位于同一个类中。
When building DDD projects I like to differentiate two responsibilities: a Repository and a Finder.
A Repository is responsible for storing aggregate roots and for retrieving them, but only for usage in command processing. By command processing I meant executing any action a user invoked.
A Finder is responsible for querying domain objects for purposes of UI, like grid views and details views.
I don't consider finders to be a part of domain model. The particular IXxxFinder interfaces are placed in presentation layer, not in the domain layer. Implementation of both IXxxRepository and IXxxFinder are placed in data access layer, possibly even in the same class.