首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“高凝聚力”的含义是什么?

“高凝聚力”的含义是什么?
EN

Software Engineering用户
提问于 2012-08-31 02:43:59
回答 3查看 16.2K关注 0票数 31

我是一名学生,最近作为实习生加入了一家软件开发公司。在大学里,我的一位教授曾经说过,我们必须努力实现“低耦合、高凝聚力”。

我理解低耦合的含义。它意味着单独保存独立组件的代码,这样一个地方的更改就不会破坏另一个地方的代码。

但是什么是高凝聚力。如果这意味着将同一组件的各个部分很好地集成在一起,我不明白这是如何变得有利的。

什么是高凝聚力?能否解释一个例子来理解它的好处?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2012-08-31 08:19:16

从面向对象的角度来看内聚力的一种方法是,类中的方法是否使用任何私有属性。使用诸如LCOM4 (缺乏内聚方法)之类的度量标准(如这个答案在这里中的gnat指出的那样),您可以识别可以重构的类。您希望重构方法或类以增强凝聚力的原因是,它使代码设计更容易被其他人使用。相信我,当你解决这些问题时,大多数技术主管和维护程序员都会喜欢你的。

您可以在构建过程中使用工具(如声纳 )来识别代码库中的低内聚力。有几个非常常见的例子,我可以想到方法的“内聚力”很低:

案例1:方法在所有

中都与类无关

请考虑以下示例:

代码语言:javascript
复制
public class Food {
   private int _foodValue = 10;

   public void Eat() {
     _foodValue -= 1;
   }

   public void Replenish() {
     _foodValue += 1;
   }

   public void Discharge() {
     Console.WriteLine("Nnngghhh!");
   }
}

其中一种方法,Discharge(),缺乏凝聚力,因为它没有触及任何类的私有成员。在这种情况下,只有一个私有成员:_foodValue。如果它没有对类内嵌做任何事情,那么它真的属于那里吗?该方法可以移动到另一个可以命名的类,例如FoodDischarger

代码语言:javascript
复制
// Non-cohesive function extracted to another class, which can
// be potentially reused in other contexts
public FoodDischarger {
  public void Discharge() {
    Console.WriteLine("Nnngghhh!");
  }
}

在Javascript中这样做,因为函数是一流的对象,因此释放可以是一个自由的函数:

代码语言:javascript
复制
function Food() {
    this._foodValue = 10;
}
Food.prototype.eat = function() {
    this._foodValue -= 1;
};
Food.prototype.replenish = function() {
    this._foodValue += 1;
};

// This
Food.prototype.discharge = function() {
    console.log('Nnngghhh!');
};
// can easily be refactored to:
var discharge = function() {
    console.log('Nnngghhh!');
};
// making it easily reusable without creating a class

案例2:实用程序类

这实际上是破坏凝聚力的常见情况。每个人都喜欢实用程序类,但这些类通常表明了设计缺陷,而且大多数情况下,代码库的维护变得更加棘手(因为与实用程序类相关的高度依赖)。考虑以下几类:

代码语言:javascript
复制
public class Food {
    public int FoodValue { get; set; }
}

public static class FoodHelper {

    public static void EatFood(Food food) {
        food.FoodValue -= 1;
    }

    public static void ReplenishFood(Food food) {
        food.FoodValue += 1;
    }

}

在这里,我们可以看到实用工具类需要访问类Food中的属性。在这种情况下,实用程序类中的方法根本没有凝聚力,因为它需要外部资源来完成它的工作。在这种情况下,在它们自己处理的类中使用方法不是更好吗(与第一种情况非常类似)?

案例2b:实用工具类

中的隐藏对象

还有另一种实用工具类,其中有未实现的域对象。程序员在编程字符串操作时的第一个反应是为它编写一个实用类。就像这里验证几个常见字符串表示的那样:

代码语言:javascript
复制
public static class StringUtils {

  public static bool ValidateZipCode(string zipcode) {
    // validation logic
  }

  public static bool ValidatePhoneNumber(string phoneNumber) {
    // validation logic
  }

}

这里大多数人没有意识到的是,邮政编码、电话号码或任何其他字符串修复本身都可以是一个对象:

代码语言:javascript
复制
public class ZipCode {
    private string _zipCode;
    public bool Validates() {
      // validation logic for _zipCode
    }
}

public class PhoneNumber {
    private string _phoneNumber;
    public bool Validates() {
      // validation logic for _phoneNumber
    }
}

这篇博文是@codemonkeyism中详细介绍了不应该直接“处理字符串”的概念,但这与凝聚力密切相关,因为程序员通过在实用程序类中放置逻辑来使用字符串。

票数 33
EN

Software Engineering用户

发布于 2012-08-31 03:26:23

高内聚力是指将相似和相关的事物保持在一起,将内容、功能、原因或目标共享的部分进行耦合或融合。换句话说,低内聚力可能意味着一个功能/类/代码实体,它服务于多个目的,而不是“指向”。其中一个承载的想法是做一件事并把它做好。其他可能包括这样一个明显的事实,即在许多地方,您不会复制类似的功能。这也提高了代码库的局部性,在某个地方可以找到某些类型的东西(文件、类、函数集、.)而不是散落在各处。

例如,考虑一个类提供两个或三个用途:加载/存储资源(例如文件),然后分析和显示内容。这样一个类的内聚性很低,因为它管理至少两个完全无关的任务(文件I/O、分析和显示)。高内聚力设计可以使用不同的类来加载和存储资源,分析资源,然后显示资源。

另一方面,低耦合的目的是保持不同的事物分离,这样它们之间的交互就越少越好,从而降低了复杂性并简化了设计。

票数 10
EN

Software Engineering用户

发布于 2012-08-31 02:58:02

这意味着对象的各个部分与对象的功能密切相关。这意味着,在功能或责任方面,物体内部很少或根本没有浪费。这反过来可以提高对所讨论的对象应该用于什么目的的理解。

票数 7
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/163090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档