以前寫C++的時候曾經在自己網站上發表過一個編碼“簡單性”之文章,現在編寫C#了才發現自己無意之間就會寫下一些浪費螢幕的代碼。
下面是自己編碼中偶然發現的一些案例,歡迎中等水準的程式設計者參考。因為要積累案例,是以随時更新。
--------------------------------------------------------------------------------
從語義角度看編碼簡單性的“心法”就是:隻要螢幕上有需要思量一下的代碼,則一定有辦法簡化。
所謂語義,就是“用人的思維了解的代碼的含義”。機器很容易懂a = b + c /3 * 2 ^3.14,但人就要想想這到底是想幹什麼。尤其如果新手寫的程式,老手居然看不懂,那就是語義出了問題。
案例1
這個是我一位朋友在研究所學生開卷考試中遇到的:編寫一個函數求三個整數中的最大值。
因為當時剛學C++,是以他的答案可以變成另外一道題:這個函數的目的是什麼?(如果不看函數名)
原來是:
public int Max(int a, int b, int c)
{
if (a > b)
if (a > c)
return a;
else
return c;
}
if (b > c) //有人還能把這裡寫成 c < b,也對,但更亂
return b;
正解是:
return Max(Max(a, b), c);
public int Max(int a, int b)
return (a > b) ? a : b;
後者并沒有節省多少代碼,但卻更容易了解,中真正亮點其實是Max(Max(a, b), c)中的兩個Max,很好地用人類語言解釋了自己想幹什麼。
案例2
01年做IC卡的時候遇到的一個:“卡号0X9999的顧客加入了卡組0X1234”原代碼:
“蠻力”編碼:
char cmd[46];
cmd[0]=0x04;
cmd[1]=0xF0;
cmd[2]=0x3C;
…
cmd[13]=0x99;
cmd[14]=0x99;
cmd[21]=0x12;
cmd[22]=0x34;
cmd[45]=0x00;
後來變成:
char *cmd=“04F03C……9999……1234……00”
當然要處理一下才能給卡片讀取。
這個符合做IC卡的人的習慣(他們喜歡暴露的人能閱讀的指令),但不符合編VC++的人的喜歡,是以後來有了:
AddICtoCG(9999, 1234)
以及符合測試人員的純TXT僞碼:
IC9999 CG1234
乃至僞碼群:
nIC11 CG21 PG12 P140
n CG34 PG22 P143
n CG45 P23
n PG13 P121
這些簡化工作花費了大約1周的時間(包括一個将僞碼群編輯器,以及将分解為單條指令發送給IC卡的軟體),但後來的工作是以變得非常簡單。
案例3
同期的工作,生成或解析授權碼流。原代碼:
szData[0] = szData[0] & (0xFF - 0x03) + nType & 0x03;
……以下省略大約1000行
非常瘋狂的一段代碼,但卻由一位非常豐富經驗的程式員寫成(他是我們在1.5年裡篩選4000份履歷後找到的最好的前5個人之一,他後來解釋說想先調試通過了,再封裝。是以老虎也有打盹的時候啊),結果是2個月的工作被完全放棄。
2周後變成:
新代碼大約有400行,其中CPack 和CKit的加起來是110行,開發時間是原來的1/4。
改好這段代碼後,我們定了個制度:所有代碼完成後均必須交由上級經理檢查後方可進入代碼庫。這個工作的工作量龐大,但公司之後若幹年上市了,市場占有率為國内的60%。6年後聚會的時候提到了我原來編寫的7個子產品,很高興地知道其中5個還在使用和維護,因為整體上它們都很短小簡單易于後繼者了解。
總結一下就是代碼整體上是寫給人看的而不是寫給機器看的,不能以編譯通過來作為判斷标準。
從語義的角度了解代碼簡單性,就是無論代碼長短,放眼望去就知道在幹什麼,就是簡單的代碼。
nCPack Pack(szData);
nPack << CKit(nType, 3) //程式說:我要把碼流的Type占3bit放進碼流去。
n << CKit(nLength, 4) //程式說:我要把碼流長度占4bit放進碼流去。
n << CKit(bReserved, 1) //程式說:為了對齊位元組,跳過一位吧。
n << CKit(nCode, 16)
n……
n << CKit(dwCRC, 32);
本文轉自火星人陳勇 51CTO部落格,原文連結:http://blog.51cto.com/cheny/1100072