代码之家  ›  专栏  ›  技术社区  ›  Mark Rogers

在使用单一责任原则时,您如何确定“责任”的粗粒度或细粒度?

  •  22
  • Mark Rogers  · 技术社区  · 14 年前

    在SRP中,“责任”通常被描述为“改变的理由”,因此每个类(或对象?)应该只有一个理由,即有人应该进去改变它。

    我很好奇,是否有人有任何策略的'范围',单一的责任原则,稍微不够客观?

    6 回复  |  直到 14 年前
        1
  •  30
  •   Mark Rogers    8 年前

    它可以归结为您所建模的内容。我已经做了一些广泛的写作,并提出了坚实的原则,我特别针对你的问题在我的讨论单一责任。

    以下内容首次出现在2010年1月/2月的《代码》杂志上,可在以下网站上获得: "S.O.L.I.D. Software Development, One Step at a Time"


    只有一个,改变的理由。

    第一。说起来容易吗 一个班级应该只有一个 存在的理由?实际上,没有人 存在的理由很容易 弊大于利。如果你把它带到 这是极端的,建立的类 只有一个存在的理由,你可能会结束 每个类只有一个方法。 这将导致大规模的 即使是最简单的 难以理解和理解 改变。

    一个类应该有的原因 在其中构建 系统。即使有两个概念 逻辑上不同的是 它们所处的环境可能 使他们成为一体 一样。决定 类应该更改不是基于 这个概念。当业务 观念和背景都变了, 那你就有理由改变现状了 班级。了解什么 一个班级应该承担的责任 你得先明白 应该用什么概念来概括 这一概念的实施细节 改变。

    例子。你在乎内心吗 发动机工作?你在乎吗 你有一个特定的尺寸 或者,你只关心引擎 当你进去的时候,一切正常 完全取决于 你需要使用引擎。

    如果你是一个在工厂工作的机械师 汽车商店,你可能关心 要知道具体的型号 各种零件尺寸,以及其他 发动机的技术规格。如果你 没有这些信息, 你可能无法维修发动机 适当地。但是,如果你是一个 需要从A点到 信息水平。关于 滑轮、皮带等几乎 你开的车有发动机

    引擎示例直接驱动到 原则。驾驶汽车的背景 汽车与维修引擎提供 两种不同的观念 改变的理由。在 部分需要分开。你需要 规范。在 不过,开车的时候,发动机是个问题 单一的概念,不需要 被进一步分解。你会的 可能只有一个类叫做 引擎,在这种情况下。无论哪种情况, 上下文决定了 适当分离

        2
  •  4
  •   ewernli    14 年前

    我倾向于用业务需求的“变化速度”来思考,而不是“变化的原因”。

    在一起 不管他们能否改变。

    差别很微妙,但对我有帮助。让我们考虑一下这个例子。 wikipedia 关于报告引擎:

    • 如果报告的内容和模板同时更改的可能性很高,则 可以 是一个组成部分,因为他们显然是相关的(也可以是两个)

    • 但是如果内容在没有模板的情况下发生变化的可能性很重要,那么 必须

    但我知道这是对SRP的个人解释。

    另外,我喜欢的第二种技巧是:“用一句话描述你的班级”。它通常帮助我确定是否有明确的责任。

        3
  •  4
  •   Chris Nicola    11 年前

    我不认为将两个数字相加这样的任务视为一种责任。责任有不同的形状和大小,但它们肯定应该被视为比执行单一职能更大的东西。

    为了更好地理解这一点,明确区分类负责什么和方法做什么可能是有帮助的。一个方法应该“只做一件事”(例如,添加两个数字,尽管在大多数情况下,“+”是一个已经做了这件事的方法),而一个类应该向它的使用者呈现一个明确的“责任”。它的责任远高于一种方法。

    像Repository这样的类有一个明确而独特的职责。它有多种方法,如Save和Load,但明确负责为Person实体提供持久性支持。一个类还可以协调和/或抽象依赖类的职责,再次将其作为单一职责呈现给其他消费类。

    底线是,如果SRP的应用导致了单个方法类,而这些方法类的全部目的似乎只是将该方法的功能包装在一个类中,那么SRP就没有得到正确的应用。

        4
  •  3
  •   Adrian K    14 年前

    我使用的一个简单的经验法则是:责任的级别或粒度应该与所讨论的“实体”的级别或粒度相匹配。显然,方法的用途总是比类、服务或组件的用途更精确。

        5
  •  3
  •   aknon    11 年前

    @德里克·贝利:很好的解释
    一些补充:

    问题仍然存在:有没有客观的方法来定义一个给定的类是否违反了SRP?

    对于这种情况,如果通过将模糊类的责任划分为不同的类,然后衡量由于这种划分而产生的新的行为和结构关系的影响来分析模糊类的行为,这可能会很有帮助。

    一旦分拆完成,保留分拆的责任或将其重新合并为单一责任的理由立即变得显而易见。

    但我对“客观地定义阶级责任”的探索仍在继续。

        6
  •  2
  •   ejaenv    13 年前

    我不同意克里斯·尼古拉上面说的“一个类应该向它的消费者提出一个明确的”责任”

    我认为SRP是关于在类内有一个好的设计,而不是类的客户。

    对我来说,责任是什么还不是很清楚,而证明这个概念产生的问题的数量。

    “如果描述中包含 “然后它需要被分割”

    引出一个问题:极限在哪里?最后,任何有两个公共方法的类都有两个改变的理由,不是吗?

    例如:

    class Modem
      send()
      receive()
    
    Refactors to ==>
    
    class ModemSender
    class ModelReceiver
    
    +
    
    class Modem
      send() -> ModemSender.send()
      receive()  -> ModemReceiver.receive()
    

    意见是好的