目标是干净的代码
和测试
。每个函数/方法,都应该做且只有一件事。这是理论。为了说明我想与您分享一些代码然后提出问题。
假设我们需要一个方法,如果条件为真而空列表为假,则返回玩家列表。
第一种方法:一种方法:
public List<int> ListOfPlayersIDs(int InputNumber)
{
if (Condition)
{
return new List<int>(new int[] {1, 2, 3}); // return a list with items
}
else
{
return new List<int>();//return an empty list
}
}
所以这里 ListOfPlayersIDs 方法执行两件事:
- 返回玩家列表
- 验证条件是否有效,否则返回空列表
为了划分这些“功能”,我们可以使用一种方法来检查条件,另一种方法返回玩家列表。
像这样:
第二种方法:两种方法:
第一种方法
public bool ArePlayerValidForThisNumber(int InputNumber)
{
If (condition)
return true;
else return false;
//Or simply return condition;
}
第二种方法
public List<int> ListOfPlayersIDs(int InputNumber)
{
return new List<int>(new int[] {1, 2, 3}); // return a list with items
}
我的问题是:
您在编码中遵循并应用了哪种方法。 对我来说,第二个是可测试的、可重用的,并且每个方法都完全按照它的预期去做。但不只是书本上的理论吗?我读了很多代码,它不遵守这种模式。
您对此有何看法?
最佳答案
这取决于 (tm)。这取决于将代码分解为更小的方法时是否使代码更清晰、更易于理解。
就我个人而言,我会保持外部接口(interface)不变(该方法可以返回一个填充列表或空列表),否则,如果您的客户需要执行代码 if/else 子句,您可能会泄漏逻辑。另外,我会使用一种称为“两个抽象级别的代码”或“每个方法都应该下降一个抽象级别”的方法。通过这样做,最终代码可能看起来像
public List<int> ListOfPlayersIDs(int InputNumber)
{
if (methodDescribingTheBusinessCondition()) {
return methodDescribingPositiveOutcome();
} else {
return methodNameDescribingNegativeOutcome();
}
}
我们的想法是,所有这些都应该像“普通”英语一样读起来,这样阅读代码的人就可以了解发生了什么,而不必了解所有细节。这里每个方法也只做一件事,协调整个事情的方法通常称为“策略”(因为它描述了您的功能)。
如果您的方法很简单,这种抽象级别可能会使其更难理解。
最后但并非最不重要的一点是,这种方法在几本书中进行了解释(Clean Code 非常具体),它被用作专业发展的良好实践。
关于testing - 清洁代码、测试和重用性说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29569372/