Sunday, December 9, 2012

程式、設計與程式設計 - 流程圖 flowchart

程式、設計與程式設計 - 流程圖 flowchart

從大學一年級開始,我就常常被同學抓去問程式。不過,我從來不直接寫好程式給人家抄,都是要看到寫好的程式碼才會幫忙指出邏輯上的錯誤。(或是看到 註解,卻發現動作似乎不是那麼回事的程式碼。)拜此「只教你釣魚卻不給你魚」的邏輯之賜,漸漸的,來要作業的人少了,留下了真正想學東西的人。
最近跟同學吃飯的時候,聊到他們來問我程式的「感想」- 雖然被我冷嘲熱諷,但還是覺得有學到東西。尤其是最近程式越寫越大,聽到我說的一段話,覺得感觸良多:
「程式設計」為什麼叫做程式「設計」,就是因為重點在「設計」。否則它就會叫「程式撰寫」之類的東西了。
寫 程式如果不先設計,很容易花很多時間卻只寫出一個爛程式。你也許會認為,不設計可以節省時間,但是那是錯的。不先設計只會讓你寫到一半的時候不知道該怎麼 辦,然後花更多時間思考。卻又因為沒經過完整的設計,最後寫出一個不怎麼樣的(爛)程式。看著這個爛程式,你當然會想再花時間把它改好,卻因為沒有設計不 知該如何下手。但是這是你「已經」花了很多時間寫出來的程式,捨不得把它丟掉。於是花下比之前還多的時間下去除錯、增刪功能,最後還是做出一個不怎麼樣的 爛程式。然後你覺得它還是不夠好,可是又更捨不得把它丟掉(因為你已經為它付出太多了!),於是花下更多時間修改,然後更捨不得,然後修改,然後更捨不 得... 可是總歸要變成個爛程式,因為缺乏設計。死馬當活馬醫不是不行,但是可能會比直接換匹馬來的麻煩。就算真的醫好了,遇上你們這些實習醫生,這匹馬也不會變 的活跳跳,大概還是個半死不活的樣子,絕對不會比經過適當調教的健康馬跑的好。
所以,如果你們給我一個程式,我看了以後叫你重寫, 意思不是叫你直接去重寫,而是我覺得你必須重新設計你的邏輯,然後重寫。寫程式之前要先設計,是天經地義的道理。為什麼程式設計一開始要教流程圖?為什麼 計概一開始要教流程圖?為什麼組語一開始要教流程圖?都只是為了教你一套設計程式的方法。我不是說一定要畫什麼鬼流程圖,因為我自己也不畫那個東西,但是 至少要先設計過才開始寫程式。
後來,有位同學告訴我他的心得...
你知道第一次我來問你程式的時候,也是一直被罵「上課沒專心聽」、「去看課本第 xx 頁」之類的。也許當時我問的只是一些「for 迴圈怎麼用」或「switch ... case 的語法是什麼」的問題,上課老師一定教過、課本上也一定有。但是當時我只覺得「如果我上課都聽的懂、課本都看的懂,幹麻還來問你?」
後 來有一個比較大的作業,也是寫到一半拿來問你。當時你看了一眼程式碼以後,指著螢幕問我「這幾行程式碼在幹什麼?」的時候,我整個人傻掉,因為真的回答不 出來。當時你只說了「連你都不知道在作什麼的碼,寫它幹麻?」後來,你一點一點的改我的程式,一點一點告訴我哪裡可能該怎麼寫,一點一點把東西加進去,寫 出來的東西,我只覺得「這根本不是我寫的!」。
最後終於全部寫完、可以正確跑出結果,但是我還是霧煞煞。這個時候你又做了另一件讓 我吐血的事 - 把視窗整個關掉,跟我說「好啦!我已經告訴你該怎麼寫了,回去以後自己重寫一次。」當時我整個人抓狂,那是我花了三天才寫出來的東西,你看了兩個小時、改 了一堆東西以後叫我重寫?
後來我回去以後當然沒重寫,又抓著原來那塊半死不活的程式屍體改來改去,花了一個晚上,寫出了一個勉強可以跑,但是很多功能做不到的爛程式。當時的感覺,就真的是捨不得把它丟掉重寫一個。
突然之間,我終於知道為什麼新手容易寫出爛程式,除了技術功力以外,最根本的問題就是他們懶的作設計。許多老師在一開始給的都只是小程式 (Hello World!),幾乎一看就可以知道該怎麼寫,或是只要照著黑板抄就會跑,不需要什麼設計。很多時候,連為什麼要這樣寫都不知道。但是,隨著課程的深入, 依樣畫葫蘆已經不能作出作業。可是因為之前沒有設計解法的能力,所以想破頭也不知道該怎麼把答案弄出來。
後來繼續聊下去,發現大家都不知道該怎樣作設計才好。我是覺得,雖然有許多文章要你別再畫流程圖了,但是那是寫給已經畫過幾百張流程圖的老手看的,新手還是得從流程圖開始。所以,畫流程圖的時候...
  1. 不要超過一張 A4 紙(即使有那些「至下頁」的小圓點,你還是不會知道自己在畫些什麼的!相信我。)
  2. 不要過度詳細(如果一個方塊對一行程式碼,直接去寫就好了,別浪費時間畫圖。)
  3. 從 大問題開始畫起(例如,直接畫「程式開始 -> 擷取聲音 -> 傅立葉轉換 -> RLE 編碼 -> 赫夫曼編碼 -> 存檔 -> 結束」,別把 FFT、RLE、Huffman Encoding 到底怎麼做畫進同一張圖內。)
  4. 解決小問題(慢慢開始畫出怎樣開音效卡、怎樣收麥克風、讀進來的串流應該放在哪裡...)
  5. 照著畫出來的東西用手算一遍,看看有沒有邏輯錯誤。
  6. 把鍵盤拉過來開始打程式。
所以... 新手們...... 看看這篇文章,然後回去畫流程圖吧!!!

Reference:
http://palatis.blogspot.ca/2005/10/blog-post_30.html

No comments: