大家覺得在接手遺留代碼時,見到什么東東是最讓人感到不耐煩的?復雜無比的 UML ?我覺得不是。我的答案是,超過兩個 else 的 if ,或者是超過兩個 case 的 switch ?墒窃诖a中大量使用 if else 和 switch case 是很正常的事情吧?錯!絕大多數(shù)分支超過兩個的 if else 和 switch case 都不應(yīng)該以硬編碼( hard-coded )的形式出現(xiàn)。
復雜分支從何而來
首先我們要討論的第一個問題是,為什么遺留代碼里面往往有那么多復雜分支。這些復雜分支在代碼的首個版本中往往是不存在的,假設(shè)做設(shè)計的人還是有點經(jīng)驗的話,他應(yīng)該預(yù)見將來可能需要進行擴展的地方,并且預(yù)留抽象接口。
但是代碼經(jīng)過若干個版本的迭代以后,尤其是經(jīng)過若干次需求細節(jié)的調(diào)整以后,復雜分支就會出現(xiàn)了。需求的細節(jié)調(diào)整,往往不會反映到 UML 上,而會直接反映到代碼上。例如說,原本消息分為聊天消息和系統(tǒng)消息兩類,設(shè)計的時候自然會把這設(shè)計為消息類的兩個子類。但接著有一天需求發(fā)生細節(jié)調(diào)整了,系統(tǒng)消息里面有一部分是重要的,它們的標題要顯示為紅色,這時候程序員往往會做如下修改:
在系統(tǒng)消息類上面加一個 important 屬性
在相應(yīng)的 render 方法里面加入一個關(guān)于 important 屬性的分支,用于控制標題顏色 程序員為什么會作出這樣的修改?有可能因為他沒意識到應(yīng)該抽象。因為需求說的是「系統(tǒng)消息里面有一部分是重要的」,對于接受命令式編程語言訓練比較多的程序員來說,他或許首先想到的是標志位──一個標志位就可以區(qū)分重要跟不重要。他沒想到這個需求可以用另一種方式來解讀,「系統(tǒng)消息分為重要和不重要兩種類別」。這樣子解讀,他就知道應(yīng)該對系統(tǒng)消息進行抽象了。
當然也有可能,程序員知道可以抽象,但基于某些原因,他選擇了不這樣做。很常見的一種情況就是有人逼著程序員,以犧牲代碼質(zhì)量來換取項目進展速度──加入一個屬性和一個分支,遠比抽象重構(gòu)要簡單得多,如果要做10個這種形式的修改,是做10個分支快還是做10個抽象快?區(qū)別顯而易見。
當然, if else 多了,就有聰明人站出來說「不如我們改成 switch case 」吧。在某些情況下,這確實能夠提升代碼可讀性,假設(shè)每一個分支都是互斥的話。但是當 switch case 的數(shù)量也多起來以后,代碼一樣會變得不可讀。
復雜分支有何壞處
復雜分支有什么壞處?讓我從百度 Hi 網(wǎng)頁版的老代碼里面截取一段出來做個例子。
switch (json.result) { case "ok": switch (json.command) { case "message": case "systemmessage": if (json.content.from == "" && json.content.content == "kicked") { /* disconnect */ } else if (json.command == "systemmessage" || json.content.type == "sysmsg") { /* render system message */ } else { /* render chat message */ } break; } break;
出處:百度泛用戶體驗
責任編輯:bluehearts
上一頁 下一頁 從if else到switch case再到抽象 [2]
◎進入論壇網(wǎng)頁制作、WEB標準化版塊參加討論,我還想發(fā)表評論。
|