存储库,服务或域对象 - 逻辑属于哪里?

时间:2010-06-04 22:14:48

标签: oop domain-driven-design repository-pattern business-logic

采取这个简单,人为的例子:

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 个答案:

答案 0 :(得分:3)

存储库负责特定于应用程序的对象的处理。这自然涵盖了查询以及设置修改(插入/删除)。

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

答案 1 :(得分:2)

这些都是很好的问题。能够确定您应该使用哪些这些取决于您的经验和您正在处理的问题。

我建议你读一本像福勒的patterns of enterprise architecture这样的书。在本书中,他讨论了你提到的模式。最重要的是,他为每个模式分配了责任。例如,域逻辑可以放在服务层或域层中。每种都有利弊。

如果我决定使用服务层,我会为图层分配处理事务和授权的角色。我喜欢保持“瘦”并且没有域逻辑。它成为我的应用程序的API。我保留所有业务逻辑与域对象。这包括对象的算法和验证。存储库检索并保留域对象。这可能是数据库列与简单系统的域属性之间的一对一映射。

我认为GetAtcitveUsers可以用于存储库。您不希望从数据库中检索所有用户并找出应用程序中哪些用户处于活动状态,因为这会导致性能不佳。如果ActivateUser具有您建议的业务逻辑,则该逻辑属于域对象。持久化更改是存储库层的责任。

希望这有帮助。

答案 2 :(得分:2)

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

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

Finder负责查询域对象,例如网格视图和详细信息视图。

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