我們在編寫代碼的過程中,有時會因為復雜的業務,導致我們編寫的代碼圈復雜度過大,if...then...else
過多嵌套,寫完的代碼可能是這樣...
這種代碼給人的第一感覺就是很美膩(對稱美),除此之外,我想不到了...... 但它的壞處就很明顯了。在寫這個代碼的時候也許只有兩個人可以懂(上帝和你自己),寫完之后我想可能就只有一個人懂了(不是你自己。而是上帝)。
當然了這樣的代碼如果沒有 bug 還好,萬一遇到了 bug 而原作者又不在,那么這段神奇的代碼將可能會被另一個(yu)神(mei)奇的作者換成另一段神奇的代碼,并以此 loop 下去......
So...... 如果這是自己寫的代碼,那么趁著還沒人發現,趕緊重構下吧...
1 Decompose Conditional(分解條件表達式)
怎么說
將 `if...then...else` 中的代碼塊抽離出來
為什么
提高代碼可讀性
怎么做
先來看段代碼
eg:假如一家商場對商品進行打折,價格在 100 - 200 之間的打八折,其它的按原價出售((hen)不(bie)合(jiao)適的栗子)。
function calculatePrice(price) {
let result;
if (price >= 100 && price < 200) {
result = price * 0.8;
} else {
result = price;
}
return result;
}
代碼很簡單,好像沒什么好重構的,但是代碼想要表達的意圖和業務的聯系并不是很大,也就是說我們把前面對業務的介紹去掉,那么代碼就不具備任何可讀性了(代碼不能很好的表達自己的用途),現在我們對代碼進行重構。
function calculatePrice(price) {
let result;
if (isDiscount(price)) {
result = discount(price);
} else {
result = price;
}
return result;
}
function isDiscount(price) {
return price >= 100 && price < 200;
}
function discount(price) {
return price * 0.5;
}
現在我們再來讀這段代碼,會發現可讀性提高了,我們在讀到第一個if
時,我們不需要再去思考里這個判斷語句是什么意思,我們可以直接根據方法名 isDiscount()
就可以知道,這是在判斷是否需要打折,需要的話就打折,不需要的話原價返回,這樣我們就可以把注意力放在代碼的整體邏輯上,而不需要在把過多的注意力放在細節方面。
2 Consolidate Conditional Expression(合并條件表達式)
怎么說
把結果相同的條件表達式合并成一個獨立的函數。
為什么
提高代碼可讀性
怎么做
再來個蹩腳的栗子
eg:某商場再次打折商品,價格大于200的商品打五折,前提是要買夠五件該商品。
function calculatePrice(price, num) {
if (price < 200) return price * num;
if (num < 5) return price * num;
return price * num * 0.5;
}
先蹩說話,先進行第一步重構
function calculatePrice(price, num) {
if (price > 200 || num < 5) return price * num;
return price * num * 0.5;
}
第二步重構請參考 Decompose Conditional。
3 Consolidate Duplicate Conditional Fragments (合并重復的條件片段)
怎么說
將條件表達式內的重復語句塊搬移到條件表達式外
為什么
減少重復代碼
怎么做
比較簡單,就直接上代碼
function calculatePrice(price) {
let result;
if (price < 200) {
result = discount(price);
result -= 10; //重復代碼
} else {
result = price;
result -= 10;//重復代碼
}
return result;
}
重構下
function calculatePrice(price) {
let result;
if (price < 200) {
result = discount(price);
} else {
result = price;
}
result -= 10;
return result;
}
4 Replace Nested Conditional with Guard Clauses(以衛語句替代嵌套條件表達式)
怎么說
使用衛語句表示所有的特殊情況(一旦找到結果就可以立即返回)
衛語句: 如果某個條件比較特殊,就應該單獨檢查該條件,并當該條件為真時立即返回。
為什么
提高代碼可讀性
怎么做
摘抄一個《重構》中的栗子:
一個薪冊系統,以特殊來處理死亡、駐外、退休員工的薪資。
function getPayAmount() {
let result;
if (isDead) {
result = deadAmount();
}else{
if(isSeparated) {
result = separatedAmount();
}else {
if(isRetired) {
result = retiredAmount()
}else {
result = normalAmount();
}
}
}
return result;
}
額額額,我覺得很少人會寫出這樣的代碼吧,很羅嗦,來看看重構后的代碼
function getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated)return separatedAmount();
if (isRetired)return retiredAmount();
return normalAmount();
}
雖然我們寫代碼不會像第一種那樣繁瑣,但使用衛語句我們可以讓代碼的可讀性大大提高,并提高代碼的效率(遇到 return 就結束,不會再向下執行)。