代码库、服务或领域对象——逻辑应该属于哪里?

8

请看这个简单的、虚构的例子:

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);
3个回答

3
这些都是很好的问题。能够确定应该使用哪种方法取决于你的经验和你正在解决的问题。
我建议阅读《企业架构模式》这样的书籍,例如Fowler的patterns of enterprise architecture。在这本书中,他讨论了你提到的模式。但最重要的是,他为每个模式分配了一个责任。例如,域逻辑可以放在服务层或域层中。每个选择都有利弊。
如果我决定使用服务层,我会将处理事务和授权的角色分配给该层。我喜欢保持它“轻”,并且没有域逻辑。它成为我的应用程序的API。我将所有业务逻辑都与域对象一起保留。这包括对象的算法和验证。存储库检索和保存域对象。对于简单的系统,这可能是数据库列和域属性之间的一对一映射。
我认为GetAtcitveUsers对于存储库来说是可以的。你不想从数据库中检索所有用户并找出哪些用户在应用程序中处于活动状态,因为这会导致性能下降。如果ActivateUser像你所建议的那样具有业务逻辑,则该逻辑属于域对象。更改的持久化是存储库层的责任。
希望这可以帮助到你。

1
回应您的最后一段话:如果“持续变化”是唯一的逻辑,那该怎么办呢?例如,ActivateUser() 只是更新用户表中的一个记录和激活码表中的一个记录。这是否构成“逻辑”?如果不是,那什么才是呢? - betitall

3

仓库负责应用程序特定处理对象的集合。这自然涵盖了查询和集合修改(插入/删除)。

ActivateUser 操作单个对象。需要检索该对象,然后进行修改。仓库负责从集合中检索对象;另一个类将负责调用查询并使用对象。


2

在构建DDD项目时,我喜欢区分两个职责:Repository和Finder。

Repository负责存储聚合根并检索它们,但仅用于命令处理。通过命令处理,我指执行用户调用的任何操作。

Finder负责查询领域对象以满足UI的需求,例如网格视图和详细视图。

我不认为Finder是领域模型的一部分。特定的IXxxFinder接口位于表示层,而不是领域层。IXxxRepository和IXxxFinder的实现都放置在数据访问层中,可能甚至在同一个类中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接