自從開發Web後端,學寫C#,從無到有也將近三年。過程中上過一些課,經過一些同事或教練的啟發,了解代碼應該如何讓簡潔乾淨,加速看代碼的人的理解時間,降低產品維護的成本。
學到新技巧就需要練習,如果直接從Legacy Code開始,自己就常常會遇到遺留代碼相依很多不好調整,導致學了技術卻很難直接應用在產品上。透過練習 Kata 從比較簡單的情境開始練習,不斷的重構,讓簡單的 Kata 可以寫的乾淨,往後在遇到複雜情境時,才能更有效的組織代碼結構。
另外一個比較難發現的困難點是,很多時候資深同事討論的或教練講述的技術,自己當下覺得有道理,等到實際要用的時候才發現卡卡的。透過練習Kata,寫完之後反覆琢磨,才能真正的把知識收入囊中。
這是一段Kata代碼,可以發現所有邏輯都直接攤平方法中,每一行都需要仔細地閱讀才能了解其目的。整個方法讀下來需要花不少時間。
public int Play(int count, int step)
{
var startArray = Enumerable.Range(1, count).ToList();
int start = 0;
while (startArray.Count() != 1)
{
var toRemove = (start + step - 1) % startArray.Count();
startArray = startArray.Where((i, index) => index != toRemove).ToList();
start = toRemove;
}
return startArray.First();
}
但是如果透過簡單的Extract Method和Rename Variable,讓變數與方法名稱來凸顯主要邏輯,讓其他人閱讀起來可以更清楚理解代碼的邏輯。
public int Play(int count, int step)
{
var candidates = Enumerable.Range(1, count).ToList();
int start = 0;
while (!HasSurvivor(candidates))
{
var victim = FindVictim(step, start, candidates);
candidates = RemoveVictim(candidates, victim);
start = victim;
}
return candidates.First();
}
private List<int> RemoveVictim(List<int> candidates, int victim)
{
return candidates.Where((_, index) => index != victim).ToList();
}
private int FindVictim(int step, int start, List<int> candidates)
{
return (start + step - 1) % candidates.Count();
}
private bool HasSurvivor(List<int> candidates)
{
return candidates.Count() == 1;
}
每次寫完代碼之後,可以自己反覆Review代碼,思考如何提升代碼的可讀性,然後可以再進一步思考代碼的可擴充性,讓未來需求發生變化時,讓代碼更容易維護。
"透過練習 Kata 從比較簡單的情境開始練習,不斷的重構,讓簡單的 Kata 可以寫的乾淨,往後在遇到複雜情境時,才能更有效的組織代碼結構。" 金句!