嘿嘿...今天的活比較爽!前幾天寫了點破程序,今天改改就搞定了。
哎,真困!喝點咖啡,靠在我的小椅子上,看看我的代碼...
神奇,這是啥?
void f()
{
TextHandler t;
t.sendText("Hello, world", true);
// ...
}
後面那個true是什麼東東?翻翻定義:
class TextHandler
{
public:
void sendText( const std::string & msg,
bool sendNewLine );
//...
};
喝點coffee,我想起來了,true表示sendText函數自動加上一個回車換行,我怎麼忘了?
難道是我笨?我陷入迷茫的沉思...
砰!!!的一聲巨響,我一慌張,嘴裡的咖啡差點噴出來,還好我嘴緊。一定是Guru合上了她的什麼大頭書。我轉向她,擠出一點微笑。她手裡拿著一本不到一百頁的小冊子。神奇,這麼小的書弄得這麼響,她是怎麼弄得?
顯然,她什麼都知道了。
"我的寶貝!假如你這麼快就忘了參數的含義,那麼當其他程序員第一次看你的代碼的時候,他怎麼明白你要表達的意思呢?"
"嗯,是啊" 我咕噜道 "但是在IDE裡面,他只要把鼠標移到函數上,他就可以看到參數說明了啊!"
"有些IDE如此,並非全部,甚至不是大多數!我說過很多次,源代碼最主要的用途是用來交流,對意圖的交流。我手中這本古老的,令人尊敬的卷冊闡述了交流的藝術。在這兒,它寫道,'使用明確,具體,具體的語言'[1],你代碼中的bool與此無緣,他不能傳遞任何有用的信息給讀者。 "
"不哈,一旦他知道這個bool是什麼意思,就很輕易記住了哈!"我中氣不足的說。
Guru用她漂亮而堅定的藍眼睛盯著我,我心裡撲通撲通跳起來。
"你多久以前寫的這段代碼?"Guru很溫柔的說道--那種我喜歡的溫柔。
"嗯,好,嗯,那如何改正呢?"我巧妙的回避她的問題。
"你不能另外想一種方式去表達你的意圖嗎?"她也不直接回答我,我們就似乎在煎雞蛋。
"我可以不要第二個參數,讓用戶自己加 '
' 好了。"我邊說邊寫:
{
t.sendText("Hello, world
");
}
"假如傳遞給sendText是一個變量呢?" Guru問。
"那就這樣好了"
{
t.sendText( variable );
t.sendText( "
" );
}
我抬頭看到Guru臉色不善,趕緊說道:
"那就這樣,我提供兩個函數"
void sendText( const std::string & );
void sendTextWithNewLine( const std::string & );
"沒有其他的辦法了嗎?"Guru思考的時候,微微皺眉。
哎,看來我今天不要想輕松溜走了,我一陣猛想......什麼也沒想出來,我投降了,"就這樣吧!"
"關於你的問題,你還要熟悉一點" Guru寫道:
void displayText( const std::string &,bool applyItalics, bool applyBold );
void f(){
displayText( "This is bold but not italic",true, false );
}
"假如一個程序員要用斜體顯示文字,但是弄錯了參數順序,那麼這些文字就要用粗體顯示了,而且
顯然編譯器無法發現這個錯誤。"
"假如Bob拿到了這段代碼,改變了參數的順序,一種叫做'Permute And Baffle'的技術[2]。會怎樣?"
"顯然,問題多多的displayText不能得到 '明確,具體,具體' 的參數。"
"現在來看你的問題,你的第一個方案,因為displayText需要其他參數而沒法用。你的第二個方案,
可以工作,但是假如displayText需要很多信息,比如顏色,字體等,你是不是要提供如此多的函數呢?"
"所以,我們可以用enumerated."
"Enumerations?"我希奇的說。
"是的,Enumerations在這兒能得到很好的應用,看,"
class TextHandler
{
public:
enum NewLineDisposition { sendNewLine, noNewLine };
void sendText( const std::string &, NewLineDisposition );
};
void f()
{
TextHandler t;
t.sendText( "Hello, ", TextHandler::noNewLine );
t.sendText( "world", TextHandler::sendNewLine );
}
"這種寫法很好,這段代碼現在self-documenting了,不需要注釋,意圖和結果都很清楚。看的人不需要去查找函數的定義了。"
"而且,這種寫法有很好的擴展性,假如你需要只加一個回車,你只需要在enumeration中加上prependNewLine就可以了,現有的代碼無需任何改變。"
"不要拋棄你第一個方案,寶貝。在有的情況下,他是最優的。"Guru轉過身,重新打開那本書,優雅而輕快的走開,消失在拐角處。
注解:
[1] William Strunk Jr. and E.B. White. The Elements of Style (MacMillan Publishing Co. Ltd,
1979).
[2] From Roedy Green's "How To Write Unmaintainable Code,"
<http://mindprod.com/unmaindesign.Html>. (Primarily aimed at Java programmers, it still has
lots of relevance for C++ programmers.)