千萬不要把 bool 設計成函數參數

我們有很多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為作為函數參數了。除非兩個原因:

  1. 你100%確認不會帶來閱讀上的問題,比如Java的 setVisible (bool).

  2. 你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

(0)
s19930811s19930811
上一篇 2016-07-10
下一篇 2016-07-10

相關推薦

  • 20160810作業

    1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。           2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root…

    Linux干貨 2016-08-12
  • Week 1–Linux基礎1

    一. 計算機是由什么組成的? 計算機有什么作用呢?  1.計算機是由硬件系統與軟件系統兩大部分組成的. 那么是什么呢?  硬件系統: 1.1 輸入組件(如鼠標,鍵盤等); 輸出組件(顯示器,打印機等); 1.2 核心大腦–CPU(里面包含有 算術邏輯、控制、記憶等單元); 1.3 為了與以上2大重要部件連接的,肯定需要一個可以…

    Linux干貨 2016-12-05
  • LVM相關使用

    前言: LVM是 Logical Volume Manager(邏輯卷管理)的簡寫,它是Linux環境下對磁盤分區進行管理的一種機制,它由Heinz Mauelshagen在Linux 2.4內核上實現,Linux用戶安裝Linux操作系統時遇到的一個常見的難以決定的問題就是如何正確地評估各分區大小,以分配合適的硬盤空間。普通的磁盤分區管理方式在邏輯分區劃分…

    Linux干貨 2017-08-13
  • httpd配置

    1、Centos7系統下實現httpd-2.2的安裝,并分別實現prefork、worker、event等幾種工作方式

    2、簡述request報文請求方法和狀態響應碼

    3、詳細描述httpd虛擬主機、站點訪問控制、基于用戶的訪問控制、持久鏈接等應用配置實例

    Linux干貨 2018-02-05
  • 文件系統上的權限管理

                        文件系統上的權限管理: 一 、三種權限       &nbs…

    Linux干貨 2017-04-03
  • Homework Week-6 vim使用、腳本編程

    請詳細總結vim編輯器的使用并完成以下練習題 1、復制/etc/rc.d/rc.sysinit文件至/tmp目錄,將/tmp/rc.sysinit文件中的以至少一個空白字符開頭的行的行首加#; cp /etc/rc.d/rc.sysinit /tmp/ vim /tmp/rc.sysinit 轉換為末行模式: :%s@^[[:s…

    Linux干貨 2016-09-19
欧美性久久久久