一門語言應(yīng)該是“Make simple things simple, make complex things possible”的。當(dāng)我們用語言來表達思想的時候,這門語言應(yīng)該能夠提供這樣的能力:即讓我們能夠最直接地表達我們的意思,多一分則太多,少一分則太少,好比古人形容美女:增一分則太肥,減一分則太瘦。
這個問題上,有一個我認為是廣泛的誤解,就是“KISS便意味著要精簡語言,并避免在編碼中使用‘高階’語言特性”。對此有一句話我覺得說得好:你不能通過從一門語言中去掉東西來增加表達力。高階特性是一面利刃,用得不好固然傷了自己,但這并不表明就沒有用。任何東西都是在它真正適用的地方適用,霸王硬上弓的話弓斷弦崩反而傷及自身。所以,僅僅因為高階特性容易誤用(而且高階特性的確也容易吸引人去用且容易誤用,不過這是另一個問題),就斷然在任何地方都不用并宣稱這樣才是KISS的話,便因噎廢食了。舉個例子,高階函數(shù)是有用的,如果在真正需要高階函數(shù)的地方不用高階函數(shù),那不是KISS,只能讓解決方案(或者更確切地說,workaround)更復(fù)雜。lambda函數(shù)是有用的,但如果在真正需要lambda的地方不使用lambda,也只能導(dǎo)致更復(fù)雜更不直觀的workarounds。OOP是有用的,但如果你的程序本來就只是簡單的“數(shù)據(jù)+*作”你偏要硬上OOP的話,不僅多了編碼時間,而且還降低程序的可見度和可維護性,后者就意味著項目的money。拿C++來說,這是一個廣為詬病的問題。C++的偏向底層的應(yīng)用領(lǐng)域決定了有不少地方使用C++其實就是“數(shù)據(jù)+*作”,然而很多人卻因為用的是C++編譯器,便忍不住去使用高級特性,結(jié)果把本來簡單的事情復(fù)雜化——我自己就有不少次這樣的經(jīng)歷:用了一大堆類之后,做完了回過頭來再看,這些類都干嘛來著?需要嗎?最關(guān)鍵的就是要清楚自己做的是什么事情,以及什么工具才是對你所做的事情最適合的。
說到這里不妨順便說說另一個誤解:“如果我反正用不著C++里面的高級特性,那還不如用C罷了”,鑒于C/C++的應(yīng)用領(lǐng)域,的確有不少地方是可以用C++的C部分完成得很好的,所以這個誤解被傳播得還是蠻廣泛的。這里的一個微妙的忽視在于:用C的話,你就用不到許多很好的C++庫了。用C++的話,你完全可以在你自己的編碼中不使用高階特性(說實話,這需要清醒的頭腦和豐富的經(jīng)驗,以及克制能力),但你還是可以利用眾多的C++庫來簡化你的工作的:如果一個transform明明可以搞定的你偏要寫一個for出來難道能叫KISS?如果一個vector就能避免絕大多數(shù)內(nèi)存管理漏洞和簡化內(nèi)存管理工作你偏偏要手動malloc/free那能叫KISS(我見過不少用C++編碼卻到處都是malloc/free的)?如果最直接的方式是gc你偏偏要繞一大堆彎子才能保證正確釋放那也不叫KISS(等C++09吧)。如果一個for_each(readdir_sequence(".", readdir_sequence::files), ::remove);能搞定的你偏要寫:
// in C
DIR* dir = opendir(".");
if(NULL != dir)
{
struct dirent* de;
for(; NULL != (de = readdir(dir)); )
{
struct stat st;
if( 0 == stat(de->d_name, &st) &&
S_IFREG == (st.st_mode & S_IFMT))
{
remove(de->d_name);
}
}
closedir(dir);
}
這個問題上,有一個我認為是廣泛的誤解,就是“KISS便意味著要精簡語言,并避免在編碼中使用‘高階’語言特性”。對此有一句話我覺得說得好:你不能通過從一門語言中去掉東西來增加表達力。高階特性是一面利刃,用得不好固然傷了自己,但這并不表明就沒有用。任何東西都是在它真正適用的地方適用,霸王硬上弓的話弓斷弦崩反而傷及自身。所以,僅僅因為高階特性容易誤用(而且高階特性的確也容易吸引人去用且容易誤用,不過這是另一個問題),就斷然在任何地方都不用并宣稱這樣才是KISS的話,便因噎廢食了。舉個例子,高階函數(shù)是有用的,如果在真正需要高階函數(shù)的地方不用高階函數(shù),那不是KISS,只能讓解決方案(或者更確切地說,workaround)更復(fù)雜。lambda函數(shù)是有用的,但如果在真正需要lambda的地方不使用lambda,也只能導(dǎo)致更復(fù)雜更不直觀的workarounds。OOP是有用的,但如果你的程序本來就只是簡單的“數(shù)據(jù)+*作”你偏要硬上OOP的話,不僅多了編碼時間,而且還降低程序的可見度和可維護性,后者就意味著項目的money。拿C++來說,這是一個廣為詬病的問題。C++的偏向底層的應(yīng)用領(lǐng)域決定了有不少地方使用C++其實就是“數(shù)據(jù)+*作”,然而很多人卻因為用的是C++編譯器,便忍不住去使用高級特性,結(jié)果把本來簡單的事情復(fù)雜化——我自己就有不少次這樣的經(jīng)歷:用了一大堆類之后,做完了回過頭來再看,這些類都干嘛來著?需要嗎?最關(guān)鍵的就是要清楚自己做的是什么事情,以及什么工具才是對你所做的事情最適合的。
說到這里不妨順便說說另一個誤解:“如果我反正用不著C++里面的高級特性,那還不如用C罷了”,鑒于C/C++的應(yīng)用領(lǐng)域,的確有不少地方是可以用C++的C部分完成得很好的,所以這個誤解被傳播得還是蠻廣泛的。這里的一個微妙的忽視在于:用C的話,你就用不到許多很好的C++庫了。用C++的話,你完全可以在你自己的編碼中不使用高階特性(說實話,這需要清醒的頭腦和豐富的經(jīng)驗,以及克制能力),但你還是可以利用眾多的C++庫來簡化你的工作的:如果一個transform明明可以搞定的你偏要寫一個for出來難道能叫KISS?如果一個vector就能避免絕大多數(shù)內(nèi)存管理漏洞和簡化內(nèi)存管理工作你偏偏要手動malloc/free那能叫KISS(我見過不少用C++編碼卻到處都是malloc/free的)?如果最直接的方式是gc你偏偏要繞一大堆彎子才能保證正確釋放那也不叫KISS(等C++09吧)。如果一個for_each(readdir_sequence(".", readdir_sequence::files), ::remove);能搞定的你偏要寫:
// in C
DIR* dir = opendir(".");
if(NULL != dir)
{
struct dirent* de;
for(; NULL != (de = readdir(dir)); )
{
struct stat st;
if( 0 == stat(de->d_name, &st) &&
S_IFREG == (st.st_mode & S_IFMT))
{
remove(de->d_name);
}
}
closedir(dir);
}

