【问题标题】:Repository, Service or Domain object - where does logic belong?存储库、服务或域对象 - 逻辑属于哪里?
【发布时间】:2011-02-28 00:29:12
【问题描述】:

举这个简单的、人为的例子:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      我建议阅读 Fowler 的 patterns of enterprise architecture 之类的书。在本书中,他讨论了您提到的模式。最重要的是,尽管他为每个模式分配了责任。例如,域逻辑可以放在服务层或域层中。各有利弊。

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

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

      希望这会有所帮助。

      【讨论】:

      • 回应你的最后一段:如果“坚持改变”是唯一的逻辑。例如ActivateUser() 只更新 User 表中的一条记录和 ActivationCode 表中的一条记录。这是否构成“逻辑”?如果不是,那是什么?
      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多