【问题标题】:Single Responsibility Principle : class level or method level单一职责原则:类级别或方法级别
【发布时间】:2015-11-28 07:45:35
【问题描述】:

我在理解单一职责原则方面有问题。 SRP 应该应用在类级别还是方法级别。 假设我有学生班,我需要创建学生,更新学生和删除学生。 如果我创建一个包含这三个操作的方法的服务类,这是否违反了 SRP 原则。

【问题讨论】:

  • 这是一个简单的启发式...如果你不能在不使用“and”这个词的情况下描述事物的工作(无论是方法、类甚至模块),那么你需要将它分解。您的服务类“管理学生对象”,因此满足 SRP。 :-)
  • SRP 仅适用于班级级别。在方法层面是不同的原则:What is the scope of the Single Responsibility Principle?

标签: oop design-principles


【解决方案1】:

SRP 处于类和方法级别。因此,如果您在谈论学生类,那么在这种情况下,它只负责对学生实体进行 CRUD。同时,当您谈论方法时,您不应该拥有一个 InsertStudent 方法,并根据 ID 在其中执行更新和插入。这会破坏 SRP。但是如果您有 InsertStudent 插入和 UpdateStudent 更新它遵循 SRP

【讨论】:

    【解决方案2】:

    我会说你有一个服务类,它负责对Student 类型的对象进行 CRUD 操作。我完全不认为这种设计违反了 SRP。
    引用自http://www.developerfusion.com/article/137636/taking-the-single-responsibility-principle-seriously/

    同一个类(甚至不同类)的两个方法应该关注不同的方面。但是,同一类中的两个方法,例如一个存储库,可能都必须关注相同的更高级别的责任,例如持久性。

    我将 CRUD 视为单一上下文中的众所周知的操作,除非您有一些与之相关的业务。例如,您可能希望允许某些类只能读取数据并拒绝它们对其进行任何更改。那时您可以利用另一个 SOLID 原则 Interface segregation
    您可以定义一个接口,其中只定义了要在这些类中使用的读取方法。或者,如果有意义(例如性能方面),创建一个单独的具体类来实现读取操作。

    【讨论】:

    • 我的困惑是单一职责的定义是巨大的,如果我有批处理,我必须处理数据实际上是单一职责,这个职责包括读取、处理和写入。那么我的班级应该全部三个,还是应该为每个班级开设三个不同的班级
    • 它是开放的,我同意。人们可以从 SRP 的一般定义中解释这两种结果。这在模式和实践中并不少见。这实际上取决于您如何对需求进行分类和抽象。例如对我来说,一个方法不应该负责添加和更新。但是这些方法可以驻留在负责保存学生数据的同一个类中。在我看来,为 CRUD 操作设置单独的类只是过度使用该原则,除非您必须这样做(请参阅我在答案中的示例)。所以如果我不需要,我不会这样做。
    【解决方案3】:

    不要批评,因为我相信原则,但如果您可以在不使用“and”的情况下总结功能,请不要遵循说它适合的建议。使用这种逻辑,您仍然可以拥有一个巨大的单文件应用程序并在不使用“and”的情况下说出它的责任。网络浏览器是一款复杂的软件,但您仍然可以用一句话来描述它。这是完全有道理的,因为它就像一个金字塔,你应该总是能够描述顶层,而不管部分是否被分割。

    这正是我们每天对函数所做的事情。您选择一个非常简单的函数名称,它隐藏了套接字的“连接”等复杂性。从这个角度看你其实不知道事后会不会分裂。这可能是一个巨大的功能。

    恐怕还是主观的。您不想根据您用文字总结功能的能力来判断您的设计。你应该总是这样,因为这是你选择方法名称的方式,我们都知道命名很难。

    我的建议是将 SOLID 原则视为一个整体,而不是单独的规则,并围绕您认为会发生变化的内容和不太可能发生变化的内容进行区分。明显的候选人是依赖。它仍然是主观的,没有办法解决这个问题,但它会帮助你。

    我个人觉得有时很难做到,但这是值得的。我不知道你是否知道Ecto 这是一个灵丹妙药项目,但当我发现它时,我有一个“Voilà”的时刻。它在很多方面并不完美,但一般来说,Ecto 和关注点分离的事情是,一开始似乎有很多间接,但后来事情分离是有道理的。在最幸福的时刻,感觉就像是很多值得信赖的小部件。

    我曾经认为模型应该非常聪明,以至于它知道如何将自己保存到数据库中,如何验证自己,如何做各种事情,这对我来说是有意义的。但现实情况是,一旦您决定要使用另一个数据库,或者根据案例进行不同的验证等,那么您就很难摆脱困境。我敢肯定,一些开发人员从未有过这种感觉,然后就没事了。但对我来说这是一个挑战。

    很多简单的案例,但您希望每个班级尽可能少地了解。您不希望您的 Mail 类知道“紧急”的 CSS 颜色是“#FF0000”。然后更难的,比如有时你甚至不希望它知道它是“紧急的”,因为它取决于用例事实。

    这并不容易。在您的特定情况下,例如,我个人不会费心混合“创建”和“删除”,但我会确保与数据库交互就是它所做的一切。它不知道事物是否有效,是否有回调等。几乎是存储库模式。 Ecto 又是一个很好的例子,或者至少我觉得它很有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      相关资源
      最近更新 更多