同樣一個需求每個人可能採取不一樣的做法。在Sum consecutives的例子中,題目是傳入一組數字陣列,並輸出另一組數字陣列,輸出的數字陣列會把連續的數字加起來(如下圖)。
以下是兩種不同的實作方式
第一種做法
public List<int> SumConsecutives(List<int> numbers)
{
var consecutiveSums = new List<int>();
int? lastNumber = null;
foreach (var number in numbers)
{
if (number == lastNumber)
{
consecutiveSums[consecutiveSums.Count - 1] += number;
}
else
{
consecutiveSums.Add(number);
}
lastNumber = number;
}
return consecutiveSums;
}
另一種做法
public List<int> SumConsecutives(List<int> numbers)
{
var consecutiveSums = new List<int>();
for (var index = 0; index < numbers.Count; index++)
{
var consecutiveNumbers = new List<int>{numbers[index]};
while (index != numbers.Count - 1 && numbers[index] == numbers[index+1])
{
consecutiveNumbers.Add(numbers[index]);
index++;
}
consecutiveSums.Add(consecutiveNumbers.Sum());
}
return consecutiveSums;
}
每一個作法代碼並不長,大約不到二十行。但是如果想要仔細理解每個作法的邏輯,需要花上一些時間。比如第二個作法中的兩層迴圈,就會比較難理解。每個人的思考迴路不盡相同,閱讀代碼時需要一行一行的讀,慢慢的腦中架構出這個做法的思考方式。
當邏輯複雜或方法比較長的時候,很多時候可以透過抽取方法,讓方法名稱描述的目的,把方法實作方式隱藏起來,讓閱讀時可以專注在方法內容。
public List<int> SumConsecutives(List<int> numbers)
{
var consecutiveSums = new List<int>();
for (var index = 0; index < numbers.Count; )
{
var consecutiveNumbers = GetConsecutiveNumbers(numbers, index);
consecutiveSums.Add(consecutiveNumbers.Sum());
index += consecutiveNumbers.Count;
}
return consecutiveSums;
}
private List<int> GetConsecutiveNumbers(List<int> numbers, int index)
{
var consecutiveNumbers = new List<int> {numbers[index]};
while (!IsLastNumber(numbers, index) && IsNumberConsecutive(numbers, index))
{
consecutiveNumbers.Add(numbers[index]);
index++;
}
return consecutiveNumbers;
}
private static bool IsNumberConsecutive(List<int> numbers, int index)
{
return numbers[index] == numbers[index + 1];
}
private bool IsLastNumber(List<int> numbers, int index)
{
return index == numbers.Count - 1;
}
方法名稱就好像書本最前面的大綱,先用一個章節標題給閱讀的人一些概念,當讀者進到章節裡面時,才把概念化為更詳盡的實作。當往下進到方法裡面時,有助於更快理解裡面的for迴圈、while迴圈的邏輯表達的流程。把方法拆小之後,也有助於優化,關於這個部分,明天繼續使用這個例子調整,讓方法更加簡潔。
閱讀代碼就像在閱讀一本書,章節裡面有小節,小節裡面又有段落。那段落小節章節都是一種抽象,能更好的輔助閱讀。轉到閱讀代碼的情境,把一長串邏輯拆成小段小段的邏輯並花一些時間思考好的方法名稱,也是有效提高閱讀效率的一種方式。