2011年3月16日
11:41
這兩天Code Diff,看到如下的代碼,功能比較簡單,技術判斷兩個HashObject對象是否相等:
private bool Equals(IHashObject data1, IHashObject data2)
{
bool value = true;
foreach (string tempString in data1.Keys)
{
if (!string.Equals(data1[tempString], data2[tempString]))
{
value = false;
break;
}
}
return value;
}
看到這個,凡是知道“防衛語句”重構的,都會建議修改:
private bool Equals(IHashObject data1, IHashObject data2)
{
foreach (string tempString in data.Keys)
if (!string.Equals(data[tempString], hash[tempString]))
return false;
return true;
}
這樣就可以省掉一箇中間變量,順便也把不必要的“{}”刪除。看起來就比較清爽了。
開發工程師提出:“儘管這樣做很漂亮,不過我聽說有一個設計原則,就是控制塊應該是單入單出的。就是說foreach內要退出控制塊應該用break,而不是return,這樣的話代碼可能會更好閱讀”。他知道這樣原則,但是並不知道它的所以然。我也不知道,當時學過這個規則,就簡單的記下了。
回家後想明白了。用break可以讓控制塊和其他控制塊獨立運作,可以達到分而治之的目的。而如果跳轉比較複雜,那麼就需要幾個塊同時閱讀,導致混亂的局面——也就是所謂的麪條代碼。不過這裏的情況顯然不需要遵守此規則。因爲
<!--[if !supportLists]-->1. <!--[endif]-->這裏的控制塊只有兩個,無需擔心無法分而治之
<!--[if !supportLists]-->2. <!--[endif]-->這個規則主要針對亂跳的goto語句,相比之下return的問題並不大。
大家也接受了這個觀點。
後記:
過了兩天,我回顧了下代碼,覺得這個代碼其實根本不必寫。因爲Equals方法已經被IHashObject重載過了。就是說data1.Equals(data2) 和Equals(data1,data2)是等效的。呵呵。