【问题标题】:Single Responsibility Principle vs. Move Method Refactoring单一职责原则与移动方法重构
【发布时间】:2014-09-09 13:25:08
【问题描述】:

我似乎陷入了两个设计准则之间。

我有一个代表三维体积的类,它由块组成。该类提供了简单的修改方法,如AddBlockRemoveBlock

这门课我需要做几件事

首先,我需要了解有关体积的某些聚合属性,例如 GetTotalWeightGetMaximumWidth 等方法。

其次,我需要对这些卷执行转换操作,例如 ShrinkTrim,它们的功能与名称告诉您的差不多(无需深入细节,卷只是根据一些规则改变,通过添加或删除块)。这些操作有很多逻辑。

我的问题是:如果我将这些查询和转换方法添加到 Volume 类中,这是否违反了单一责任原则? 我的班级职责是:

  • 保存体积数据,允许简单修改(添加和删除块)
  • 提供有关卷的汇总信息
  • 为这些卷提供转换功能。

如果我认为这是太多的责任,并且 Volume 类应该只代表音量,我将需要创建诸如 VolumeTrimmer 之类的类VolumeShrinker 等用于转换,WeightCalculator 用于查询

最后一个选项似乎巧妙地将不同类中的关注点分开。但是,如果我查看 VolumeTrimmerTrim(Volume v) 的详细信息,它所做的只是对音量进行调用操作。同时,我的WeightCalculatorCalculateWeight(Volume v)方法似乎主要关注Volume

当我看到这种方法时,我觉得不得不使用 Move Method 重构。我查看代码并说“这个方法主要关注另一个类的属性,因此我最好将这个方法移到这个类中”。但这会将责任带回到 Volume 类!

关于我应该如何解决这个问题的任何想法?我对这些准则的理解有误吗?

【问题讨论】:

  • Volume 类对我来说似乎很奇怪。体积是某种事物的属性,例如结构。
  • @Sam:他的意思是“体积”,意思是“空间的三维区域”

标签: design-patterns refactoring single-responsibility-principle


【解决方案1】:

像往常一样,这类问题的唯一正确答案是:视情况而定。

拥有作为简单数据容器的类(例如您的卷类)通常是有意义的,但没有收缩、修剪等方法。

还可以选择仅在 Volume 类中使用 Trimmer 和 Shrinker。通过这种方式,您可以将 Volume 及其操作很好地封装在一个类中,但也可以将复杂的方法分开,这可能有助于测试。

那么如何决定哪个是正确的设计呢?以下是几个指导性问题:

  1. 对于 Shrinker 等,您是否需要在 Volume 类中将原本私有的内容公开?如果是这样,这暗示了 Volume 的方法

  2. 对于 Shrinker&Co 是否有可以想象的替代实施方案,可能用于测试目的或具有不同的性能特征?如果是这样,这暗示了单独的类。

  3. Volume 的客户大部分时间是否使用 add/removeBlock 方法和收缩和修剪方法?这将再次暗示一个班级。

  4. Shrinker&Co 是否只需要 Volume API 的一个子集?如果是这样,这暗示了单独的类。

【讨论】:

  • 感谢您提供如此全面的答案。我认为答案将是一个很大的“依赖”,但我需要确定。在前进的过程中,我会牢记您的示例。
【解决方案2】:

据我了解,单一责任原则是相当随意的,因为没有任何来自高级语言的代码只能做一件事。 话虽如此,您的 VolumeTrimmer 和 VolumeShrinker 似乎只对 Volume 属性的 子集 感兴趣。因此,分离这些类并只给它们他们感兴趣的属性子集是有意义的。这使得它们可以在另一个类也具有该子集并希望相同行为但不需要知道任何东西的其他场景中重用关于音量。 有意义吗?

【讨论】:

    【解决方案3】:

    我认为这没有问题。这似乎是Composite pattern 的一个例子。您的卷由块组成。

    您的卷没有理由不能具有卷范围的操作,例如转换,可以通过委托给块级转换操作来实现。

    【讨论】:

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