【问题标题】:Repository Pattern - Structuring repositories存储库模式 - 构建存储库
【发布时间】:2016-10-21 21:44:30
【问题描述】:

我正在尝试在我的 MVC 程序设计中使用存储库,但遇到了如何最好地构建它们的问题。

例如,假设我有一个对象 USers,我有一个 UserRepository,它具有 getUser(int id)saveUser(Dal.User model) 等功能......

所以如果在我的控制器中我有 EditUser 并且我想显示一个具有用户详细信息输入表单的视图。所以我可以这样做:

User user = _userRepository.getUserDetails(userId);

好处是我的控制器只处理 HTTP 请求,业务逻辑被移动到存储库,使测试等更容易

所以,假设我想显示此用户在我的系统中可能拥有的角色的下拉列表,即客户、管理员、员工等

是否可以在 _userRepository 中有一个名为 getPossibleUserRoles() 的函数,或者我应该有一个单独的 _roleRepository 和一个函数 getRoles() ?

为您遇到的每个实体注入一个存储库到您的控制器中是不是一个坏主意?或者在你的存储库中混合实体是一个坏主意,使它们变得杂乱无章。

我意识到我已经提出了一个非常简单的场景,但显然随着系统变得越来越复杂,您可能会谈到需要在控制器中为每个页面调用实例化 10 多个存储库。并且还可能实例化当前控制器方法中未使用的存储库,以使它们可用于其他控制器方法。

任何关于如何最好地使用存储库来构建项目的建议表示赞赏

【问题讨论】:

    标签: oop design-patterns repository-pattern


    【解决方案1】:

    可以在 _userRepository 中调用一个函数吗 getPossibleUserRoles() 还是我应该有一个单独的 _roleRepository 使用函数 getRoles() ?

    假设你有一些控制器调用:

    _userRepository.getUserDetails(userId);
    

    但他们从不打电话:

    _userRepository.getPossibleUserRoles(userId);
    

    那么你就是在强迫你的控制器依赖他们不使用的方法。

    所以这不只是好的,你应该把它分开。

    但如果getUserDetailsgetPossibleUserRoles 是选择的(共享相同的实体、共享相同的业务逻辑等)。

    除了为Roles 创建新类之外,您可以在不更改用户存储库实现的情况下拆分它。

    public class UserRepsitory : IUserRoles, IUserRepository
    {
    
    } 
    

    我意识到我提出了一个非常简单的场景,但显然 随着系统复杂性的增加,您可能会谈论 10s 需要在控制器中实例化的存储库

    如果构造函数获取的参数过多,则很有可能违反 SRP。 Mark Seemann 在here 中展示了如何解决这个问题。

    简而言之:当您创建行为时,如果您总是一起使用 2 个或多个存储库。然后,这些存储库非常接近。所以你可以创建一个服务并在这个服务中编排它们。之后,除了在控制器构造函数中使用 2 个或更多存储库之外,您还可以将此服务用作参数。

    【讨论】:

      【解决方案2】:

      可以在 _userRepository 中有一个名为 getPossibleUserRoles() 的函数,还是应该有一个单独的 _roleRepository 和一个函数 getRoles() ?

      这两种解决方案都可以接受,但请考虑您将如何控制存储库的扩散以及这些存储库上的方法。恕我直言,典型的存储库使用场景往往会导致存储库太多,每个存储库都有太多方法。 DDD 提倡每个聚合根都有一个存储库。这是一个很好的经验法则……如果您遵循 DDD 原则。

      为您遇到的每个实体注入一个存储库到您的控制器中是不是一个坏主意?或者在你的存储库中混合实体是一个坏主意,使它们变得混乱。

      注入 volatile 依赖项,所以是的,为控制器需要的每个实体注入一个存储库。但是,一旦您开始注入超过四个依赖项,您很可能在设计中的某个地方错过了抽象。有些人用RepositoryFactory 解决了这个问题,但是这可以说引入了不透明依赖的问题,而且恕我直言,它无法传达类的真正依赖关系,从而降低了它的可用性和自文档能力。

      看看使用查询对象而不是存储库(https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/ 等),看看在控制器中使用编排/中介(http://codeopinion.com/thin-controllers-cqrs-mediatr/)。我想你会发现一个更好的设计会帮助你解决你的设计问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多