【问题标题】:Low cohesion in helper/storage classes, is that really wrong?助手/存储类的内聚度低,真的错了吗?
【发布时间】:2018-02-05 08:31:10
【问题描述】:

有一个像这样的类,两个实例变量有两个getter:

class A
{
   _fieldA;
   _fieldB;

  GetA()
  GetB()

  GetSpecialNumber(int a)
  {
      //calculation not requiring any fields
  }
}

该类将被归类为完全缺乏凝聚力。但是,我相信在某些情况下需要这样的无状态对象,因此不应该应用内聚度量。或者这是一个错误的方法/想法? 事实是,除了本材料末尾提到的几个案例外,我从未读过低内聚力是好的:http://www.aivosto.com/project/help/pm-oo-cohesion.html

【问题讨论】:

  • 我看到的是一个具有只读属性的 DTO。 DTO 有什么问题?
  • 你在这里得到的并不是真正的方法,而是只读属性。所以不行。恕我直言,凝聚力指标在这里不适用。 (“不是真正的方法”= 它们不包含任何适用于字段的逻辑。)
  • @Fidor,对,那么可以说这些是对各个字段执行某些操作的方法。由于它们不能与另一个一起使用,因此内聚度为 0。
  • @user970696 不要过于关注指标。它们不是一成不变的。他们应该让您大致了解您的解决方案中发生了什么。如果您必须保持高凝聚力,那么您唯一能做的就是将该类A 分成两个类XY,它们只有一个字段
  • @EmrahSüngü 是的。我更想了解我提供的链接中的示例是否真的有效,以及在某些情况下低凝聚力是否真的是合理的。

标签: c# oop metrics cohesion


【解决方案1】:

不,低内聚度不好,至少如果您的目标是面向对象,则不会。

现在,公平起见并警告您,这可能不是多数意见,但 DTO、Bean、属性或您称之为的任何东西都没有经过精心设计(正如链接文章所暗示的那样)。同样,仅当您关心面向对象时。如果你不在乎那么多,那么你当然可以决定你想做什么。

显然存在一些微妙之处,例如给定的指标是否真的正确,或者外部力量(要求)是否将您拉向低耦合。但是,我们要避免低耦合的原因是我们希望将一起更改的东西放在一个地方以实现可维护性。低耦合的事物可能不会一起改变,因此可维护性较差

低内聚有时会导致高耦合。例如,DTO(低内聚对象)通过设计导致高耦合。每次 DTO 中的任何东西发生变化,所有使用该 DTO 的地方都需要检查。也就是说,这些地方与 DTO 高度耦合。

【讨论】:

  • 谢谢,很有趣。另外,您如何看待我在问题中引用的文章末尾提到的案例?
  • 我不同意这些案例代表好的设计。您也许可以找到非常具体的案例,这些设计可能有意义,但不是一般情况下。为了方便而对数据或程序进行分组并不是设计的好方法。
  • 我不同意这一点,使用 DTO 可以帮助您以适当的方式组织代码,使每个对象对其内容负责。随着更多的抽象(dtos),可维护性随着代码中有更多的定制点而增加。每个人都可以使用一种方法或另一种方法编写糟糕的代码,但是如果您比较 2 种合适的设计,具有 SOLID 原则的设计在定制点上是最好的,即使它的内聚度较低
  • @IvanSanz-Carasa 您可以对公开的事物负责,因为您根本无法控制它们的使用方式。 DTO 中的所有内容都是公开的,因此 DTO 没有任何责任。另外,在我看来,这也意味着它们不应该存在。
【解决方案2】:

对于这种情况,我将使用属性而不是字段,这有助于一些工具理解这是一个 DTO(这是正确的),因此他们不再抱怨内聚和代码质量。

struct X
{
    public int A { get; private set; }
    public int B { get; private set; }
}

如果GetSpecialNumber(int a) 不使用任何字段/属性,它可以是静态方法:

public static int GetSpecialNumber(int a)

如果它会在其他地方使用,我也会将它移到辅助类中。

public static class SpecialNumberHelper
{
    public static int GetSpecialNumber(int a)
    {
        // calculation not requiring any fields
    }
}

【讨论】:

  • 明白。我主要感兴趣的是低凝聚力是否可以通过实际方法变得更好。我修改了问题中的代码。现在有另一种方法不适用于任何字段,即内聚力仍然为 0。
  • 如果 GetSpecialNumber 不需要任何字段,它应该作为静态方法移动到一些通用帮助器
  • 好吧,但如果这是那个帮手?像数学类左右一样,计算平方或阶乘,您所需要的只是一个输入。我认为在这种情况下,凝聚力也会很低。
  • @IvanSanz 不一定。这真的取决于。想象一下:一个类有一个方法来为你计算一些 ID。它还提供了 2 个常量值:“EmptyID”和“PoisonID”。我会说将它们放在一个(实用程序)类中是完全合理的。
  • @user970696 助手是具有静态方法且没有状态的静态类(嗯...它们可以在内部包含静态并发内容以用于缓存等)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 2012-04-08
  • 2018-02-10
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多