我們有很多Coding Style 或 代碼規范。但這一條可能會經常被我們所遺忘,就是我們經常會在函數的參數里使用bool參數,這會大大地降低代碼的可讀性。不信?我們先來看看下面的代碼。
當你讀到下面的代碼,你會覺得這個代碼是什么意思?
widget->repaint(false);
是不要repaint嗎?還是別的什么意思?看了文檔后,我們才知道這個參數是immediate, 也就是說,false代表不立即重畫,true代碼立即重畫。
Windows API中也有這樣一個函數:InvalidateRect,當你看到下面的代碼,你會覺得是什么意思?
InvalidateRect(hwnd, lpRect, false);
我們先不說InvalidateRect這個函數名取得有多糟糕,我們先說一下那個false參數?invalidate意為“讓XXX無效”,false是什么意思?雙重否定?是肯定的意思?如果你看到這樣的代碼,你會相當的費解的。于是,你要去看一下文檔,或是InvalidateRect的函數定義,你會看到那個參數是 BOOL bErase,意思是,是否要重畫背景。
這樣的事情有很多,再看下面的代碼,想把str中的”%USER%”替換成真實的用戶名:
str.replace("%USER%", user, false); // Qt 3
TNND,那個false是什么意思?不替換嗎?還是別的什么意思,看了文檔才知道,false代碼大小寫不敏感的替換。
其實,如果你使用枚舉變量/常量,而不是bool變量,你會讓你的代碼更易讀,如:
widget->repaint(PAINT::immediate); widget->repaint(PAINT::deffer); InvalidateRect(hwnd, lpRect, !RepantBackground); str.replace("%USER%", user, Qt::CaseInsensitive); // Qt 4
如果對這個事不以為然的話,我們再來看一些別的示例,你不妨猜猜看看下面的代碼:
component.setCentered(true, false);
這什么玩意兒???看了文檔你才知道,這原來是 setCentered(centered, autoUpdate);
new Textbox(300, 100, false, true);
這又是什么?。靠戳宋臋n才知道,這是創建一個文本框,第三個參數是是否要滾動條,第四個是是否要自動換行。TNND。
上面的情況還不算最差,看看下面的雙重否定。
component.setDisabled(false); filter.setCaseInsensitive(false
)
再來一個,如果你讀到下面的代碼,相信你會和我一樣,要么石化了,要么凌亂了。
event.initKeyEvent("keypress", true, true, null, null, false, false, false, false, 9, 0);
看完這篇文章,我希望你再也不要把bool為作為函數參數了。除非兩個原因:
-
你100%確認不會帶來閱讀上的問題,比如Java的 setVisible (bool).
-
你100%確認你想去寫出無法維護很難閱讀的代碼。
【更新2011/9/8】當然,別的參數也會有一樣的問題,比如:new Textbox(300, 100, false, true);
中的300 和 100,不知道是坐標還是長寬,只不過,一般長度或坐標這樣的參數都不會被hard code,都會有變量名,而bool這種參數經常性地被傳成true 和 false。 bool參數表現得更為明顯一些罷了。
所以,程序中不要出現magic number,true/false 也是一種 magic number。但是,我想告訴大家,從API設計的角度來說,你無法強制調用者用常量來取代true/false,定義成枚舉類型是最好的選擇。
最后,如果你想設計一個好的API,強烈推薦你讀一下Nokia的Qt的《API Design Principles》,本文就是其中的“Boolean Trap”。
轉自:http://coolshell.cn/articles/5444.html
原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2165