千萬不要把 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);

這又是什么???看了文檔才知道,這是創建一個文本框,第三個參數是是否要滾動條,第四個是是否要自動換行。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 12:16
下一篇 2016-07-10 12:17

相關推薦

  • DNS服務器之配置

    一、安裝DNS服務器     DNS服務的安裝包為bind,使用yum直接安裝即可:     安裝完成后,查看DNS服務相關的文件: 二、配置正向區域     1、在配置正向區域之前,先來看下主配置文件中的內容:    &nbsp…

    Linux干貨 2015-05-03
  • Linux man中文幫助安裝

    雖然在CentOS操作系統中具有多語言包,但其man手冊是英文的,對于新手來說能夠使用中文man手冊將加快學習速度

    CentOS系統安裝中文man手冊

    Linux干貨 2017-11-26
  • 計劃任務

    作業管理: Linux的作業控制(job )     前臺作業:通過終端啟動,且啟動后一直占據終端;     后臺作業:可通過終端啟動,但啟動后即轉入后臺運行(釋放終端) 如何讓作業運行于后臺?     (1) 運行中的…

    Linux干貨 2016-09-08
  • grep正則表達式及sort、diff等相關命令

    Linux文本處理三劍客: grep:文本過濾工具(模式:patter) sed:stream editor 流編輯器,文本編輯工具 awk:linux上的實現gawk,文本報告生成器(格式化文本) * 正則表達式:Regular Expression,REGEXP,由一類特殊字符及文本字符所編寫的模式,其中有些字符其不表達字面意義,而是…

    Linux干貨 2016-12-29
  • lvs——高可用集群

    技術簡介: LVS集群采用IP負載均衡技術和基于內容請求分發技術。調度器具有很好的吞吐率,將請求均衡地轉移到不同的服務器上執行,且調度器自動屏蔽掉服務器的故障,從而將一組服務器構成一個高性能的、高可用的虛擬服務器。整個服務器集群的結構對客戶是透明的,而且無需修改客戶端和服務器端的程序。為此,在設計時需要考慮系統的透明性、可伸縮性、高可用性和易管理性 集群采用…

    Linux干貨 2016-10-26
  • Linux中的網絡功能概念介紹(一)

      在操作系統中,進程之間的通信是用ipc(內存基本通信)以及內存共享shm來實現本地的通信,那么如果跨主機間通信或者說是不同之間的主機用rpc(遠程過程調用)以及socket套接字,用一個主機在socket中寫數據,另一個主機在socket之間讀數據,以實現進程通信的最終目的。   在網絡功能出現之前,基本都是用電話…

    Linux干貨 2016-11-23
欧美性久久久久