4

当我编写一个类的公共成员函数时,它会做几件事,比如..

void Level::RunLogic(...);

在该函数中,我发现自己将其拆分为几个私有成员函数。将公共成员函数拆分为多个函数是没有意义的,因为如果没有另一个,你就不会做一件事,而且我不希望用户担心按什么顺序等等。相反,RunLogic() 函数会看起来像这样...

void Level::RunLogic(...) {
 DoFirstThing();
 DoSecondThing();
 DoThirdThing();
}

DoThing 函数是私有成员函数。在 Code Complete 中,Steve McConnel 建议减少类中的函数数量,但我宁愿不要只将所有代码放入一个函数中。我对他真正含义的假设是一个类不应该有太多的功能,但我只是想知道其他程序员对此有何看法。

此外,我一直致力于在我的公共成员函数中公开越来越少的实现细节,并将大部分工作转移到小型私有成员函数中。显然,这创造了更多的功能......但这就是问题所在。

4

7 回答 7

2

您希望保持公共方法简单,并将其功能拆分为多个私有方法是正确的。

McConnell 是正确的,您应该减少在类中保留的方法数量。

这两个目标并不矛盾。我不认为 McConnell 会提倡延长你的函数来减少它们的数量。相反,您应该考虑将其中一些私有方法推入一个或多个可供公共类使用的实用程序类中。

当然,实现这一点的最佳方法将取决于您的代码细节。

于 2009-12-17T02:23:07.310 回答
1

我建议将它们分解为单独的方法,其中每个方法处理一个小任务,并对每个私有方法进行描述。分解方法和方法名称将使逻辑代码更具可读性!相比:

double average(double[] numbers) {
  double sum = 0;
  for (double n : numbers) {
    sum += n;
  }
  return sum / numbers.length;
}

至:

double sum(double[] numbers) {
  double sum = 0;
  for (double n : numbers) sum += n;
  return sum;
}

double average(double[] numbers) {
    return sum(numbers) / numbers.length;
}

代码完成解决每个类公开的接口,而不是实现。

将这些较小的方法作为包保护可能更有意义,因此您可以轻松地对它们进行单元测试,而不是只能测试复杂的 RunLogic。

于 2009-12-17T02:16:45.950 回答
1

我同意拆分功能。

我一直被教导并坚持一个函数被定义为执行单个封装任务的知识,如果它似乎在做不止一件事,那么重构它可能是可行的。然后一个类将相似或相关的功能封装在一起。

在我看来,将这些任务分解并仍然使用单个公共成员允许一个类以它预期的方式执行该重要任务,同时使其更易于维护。我还经常发现在同一个复杂方法中有多个相似的代码部分,可以将它们重构为一个带有参数的通用函数——既提高了可读性又提高了可维护性;甚至减少代码量。

于 2009-12-17T02:26:05.490 回答
0

我使用的一条规则是三规则。如果我在不同的地方做同样的事情 3 次,那么值得拥有一个单独的(可能是私有的)成员函数来封装该共享行为。

在这种情况下,我通常使用的唯一其他规则是可读性。如果我在 IDE 中查看的成员函数超过了全屏,我发现很难跟踪所有代码路径和可能的错误转弯。在这种情况下,将一个整体成员函数分解为两个或多个私有辅助函数是完全合理的。

关于类中函数数量的 Code Complete 注释,请记住,函数数量涉及的最大风险主要与外部可用接口的复杂性有关。您为其他人提供的入口点越多,出现问题的可能性就越大(例如,由于其中一个公共成员中的错误、不正确的输入等)。添加私有成员函数不会增加公共 API 的复杂性。

于 2009-12-17T02:15:38.227 回答
0

您无意中遵循了 ff 规则:

A class should have only one reason to change / Single responsibility principle

这是一件好事。通过正确分离职责,您可以确保您的应用不会因为以下原因而轻易中断change

于 2009-12-17T02:22:56.653 回答
0

我使用的“经验法则”是,没有一个功能一次占用的空间超过一个屏幕的完整空间。虽然思想相当简单,但当您一次可以在一个屏幕上“全部接受”时,它会有所帮助。它还将限制(根据定义)任何一种方法的复杂性。当您被期望将您的工作交给同事进行进一步维护、升级和错误修复(!)时,保持简单是好的。考虑到这一点,我同意保持公共方法简单几乎总是正确的选择。

于 2010-01-19T13:07:35.977 回答
0

我看不出将公共成员函数保持尽可能小(以代码行数衡量)的优势。通常,长函数的可读性较差,因此在大多数情况下,扩展大函数的实现会提高可读性,无论它们是否属于类。

至于保持类尽可能小的好建议,这对于接口的公共部分和封装的数据量尤其重要。原因是具有大量数据成员和公共函数的类取消了数据封装的优势。

于 2009-12-17T08:07:57.880 回答