在某些情况下,比起更简洁的代码,更冗长的代码(如更逻辑的语句)更干净吗?
在某些情况下,比起更简洁的代码,更冗长的代码(如更逻辑的语句)更干净吗?
Answers:
为了回答这个问题,让我们以发生在我身上的真实世界为例。在我维护的C#库中,我有以下代码:
TResult IConsFuncMatcher<T, TResult>.Result() =>
TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
? _emptyValue.supplied
? _emptyValue.value
: throw new NoMatchException("No empty clause supplied");
: _recursiveConsTests.Any()
? CalculateRecursiveResult()
: CalculateSimpleResult(simpleMatchData);
与同龄人讨论时,一致的结论是,嵌套的三元表达式以及对的“巧妙”使用会is var
导致简洁但难以阅读的代码。
因此,我将其重构为:
TResult IConsFuncMatcher<T, TResult>.Result()
{
var simpleMatchData = TryCons(_enumerator);
if (!simpleMatchData.head.HasValue)
{
return _emptyValue.supplied
? _emptyValue.value
: throw new NoMatchException("No empty clause supplied");
}
return _recursiveConsTests.Any()
? CalculateRecursiveResult()
: CalculateSimpleResult(simpleMatchData);
}
原始版本仅包含一个带有隐式的复合表达式return
。现在,新版本包含一个显式变量声明,一个if
语句和两个explicit returns
。它包含更多的语句和更多的代码行。但是我咨询过的每个人都认为它更易于阅读和推理,这是“干净代码”的关键方面。
因此,您的问题的答案是一个明确的“是”,比简洁的代码更冗长的代码更简洁,因此是有效的重构。
!
从条件中删除。我也建议将第二个收益放在else
。但是即使如此,它还是一个巨大的进步。
if (!foo.HasValue)
在您的代码中是一个惯用语,则更是如此。但是,这if
并不是真正的提前退出-它是“取决于”。
1. LOC与代码质量之间缺乏相关性。
重构的目的是提高一段代码的质量。
LOC是一个非常基本的指标,有时与一段代码的质量相关:例如,具有数千个LOC的方法可能会出现质量问题。但是,应该指出,LOC并不是唯一的度量标准,并且在许多情况下缺乏与质量的相关性。例如,4 LOC方法不一定比6 LOC方法更具可读性或可维护性。
2.一些重构技术包括添加LOC。
如果您列举了一系列重构技术,则可以轻松地发现那些有意添加 LOC的技术。例子:
两者都是非常有用的重构技术,并且在考虑是否使用它们时,它们对LOC的影响是完全无关的。
避免使用LOC。
LOC是一个危险的指标。它非常容易测量,并且很难正确解释。
在您熟悉代码质量测量技术之前,请首先考虑避免测量LOC。大多数情况下,您不会获得任何相关信息,并且在某些情况下,它会误导您降低代码质量。
如果您想查看仅使源代码的字节数或LoC数最小化的最终结果,请查看提交给Stack Exchange Code Golf网站的提交。
如果以这种方式减少源代码,您很快就会陷入混乱。即使您是编写此类代码的人,并且当时对它完全了解,但六个月后返回时,您的效率如何?没有证据表明这样的最少代码实际上可以更快地执行。
代码的编写方式应使您团队中的任何成员都可以查看它,并立即了解它在做什么。
是的,重构肯定会导致更多的代码行。
IMO最常见的情况是,当您使用非通用代码并使之更加通用/灵活时。轻松地生成代码会使代码行显着增加(有时增加两倍或更多)。
如果您希望新通用代码被其他人(而不是作为内部软件组件)用作库,那么通常您最终会添加单元测试代码和代码内文档标记,这将再次增加代码行。
例如,这是每个软件开发人员都会遇到的非常常见的情况:
我想到了一些具体的例子: