OMG~只過了一個月,我居然看不懂當初自己寫的程式

「我當時到底在想什麼呀!」

我相信其實很多人都會有這整問題!無論是程式語言或是設計上的作品都會有。但這不就代表了妳已經進步了嗎?今天Designrock分享一篇當你遇到此種問題時該如何是避免和解決的文章妳喔!

一個多月前的時候,這些程式碼看起來就像藝術品一樣優雅、簡單,又令人驚豔,而且合乎邏輯。不過現在看起來卻不是這麼一回事。而明天就要交件了,我卻在幾個小時前發現了一個 bug,這些程式碼當時是這麼的美,現在卻連我自己都看不懂。這並不是單一個案,每次在寫程式的時候,一切看起來都是這麼的完美,幾周之後,再回頭看,卻又是總一團混亂。

你也跟我有一樣的困擾嗎?

以下有六點問題,可以幫助你重新檢視你的程式(很有效!)

問題一:過於複雜的構想

每個程式都是在解決現實生活中的某個問題,在你開始工作之前,先想想看「你要解決的是什麼問題?」,不要小看這個步驟,這大概是程式設計最困難的一個部分。

首先,先在腦海中建立一個概念,想想你寫這個程式的目的是什麼。接著,建構出一個解決方案,我們暫且稱作語意模型(semantic model)。我們常常會太執著在解決問題,而忘記這份工作原本的目的。永遠不要忘記你初衷!

第三步,盡可能想出一個最簡單的語意模型。這是第二個容易出錯的部分。如果沒有花時間去釐清問題所在,你很容易就會卡住了。從另一方面來說,如果你可以想出一個簡單的模型,來達成你的目標,那就再好不過了。刪掉那些不必要的程式碼,我們的工作已經夠複雜了,不要再把事情做得更複雜。

問題二:編碼問題

完成了簡潔有力的語意模型之後,就開始要把它轉化成一行行的程式碼。我們稱作語法模型(syntactic model)。這個步驟就是要把你腦中的概念轉化為電腦聽得懂的語言。

如果在轉換的過程中出了問題,那就代表你必須回頭來修正這個程式,這時你就會跟我一樣,看不懂自己在寫什麼。當你在寫程式的時候,你腦中的語意模型很清楚,所以你可以輕易地搞懂自己在寫什麼,但幾周之後,可就不是這麼回事。很多時候,我們會覺得「x」代表寫下的資料,「y」代表刪除的資料,很容易明白不是嗎?但是三個月後,你再回來看,這些代號一點意義都沒有。

轉換的過程之中,盡可能地留下線索,讓你之後修改或重建的過程可以更流暢。但是要怎麼做呢?

1. 類別(Class)結構和名稱

如果你使用的是物件導向的語言(OO),盡可能地讓 class 結構和名稱接近你的語意模型。領域驅動設計(Domain-Driven Design,DDD)就非常強調這個概念。即使你不完全採用這個概念,你在建構類別和命名的時候也應該要非常小心,好的分類會是一個好的提示,讓你之後在修改時能快速恢復記憶。

2. Variable、Parameter、Method 命名

Method 可以叫「PaySalesCommision」就不要取叫「Process」;Variable 可以用「currentContract」就不要用「x」;不要把 Parameter 取叫「input」,應該取叫「outstandingInvoices」。

3. 單一功能原則 Single responsibility principle (SRP)

單一功能原則強調一個 Class 或 Method 只能做一件事情。只做一件事的好處就是,在命名時,就必須想清楚它的功能和目的是什麼。如果一個類別需要讀取資料庫、計算稅率、產生發票,那你大概無法替他取「一個」好名字。我常常會回頭去修改類別名稱,因為我不知道要替他取個簡而有力的名字,或是把他所做的事情都放進名字裡。

4. 適當的 Comment

如果你必須寫下某一行程式,但你擔心自己未來可能看不多,不妨留個 Comment 給自己吧!盡可能把你的敘述詳細的寫下來,但記住,不是寫下你做了什麼,而是你為什麼這樣做。

問題三:組塊使用不足

在心理學的認知科學中,認為人類會將過長的訊息,分割成較小的組塊(Chunk),以便記憶。但是,這跟程式設計有什麼關係?程式寫久了你就會發現,有些東西總是一而再,再而三的出現。

《Elements of Reusable Object-Oriented Software》是第一本將這些設計模式(Design Patterns)列出來,並加以解釋的書。組塊的概念不僅可以用在設計模式中,也可以用在OO。在函數程式設計(Functional programming)中,也有許多標準化的功能,演算法(Algorithms)也是一種組塊的概念(稍後會再提到)。

當你開始採用組塊的技巧時,你就不必再思考這個你的程式要如何產生這些效果了,而是思考他能做什麼!這可以大幅縮短你的語意模型和語法模型的距離,也就是你腦中的構想和實際程式碼之間的距離,兩者之間的距離越相近,你就越容易理解和掌握這些程式碼。

如果你想要學習更多有關函數程式設計的東西,歡迎來我的網站上走走( functional programming for web developers)。

問題四:不明確的功能

我們提到了很多次,有關結構和命名的重要性,還有另一件很重要的事情就是,你必須清楚地知道要如何使用這些方法。在強調一次,你在寫的時候,當然會很清楚知道為什麼、怎麼使用這些類別和方法,但當你隔了一陣子,再回來看,想要重整出當時的邏輯和想法可不容易,因為通常不同的功能會散落在你程式的各個角落,有時候甚至是在其他專案中。

測試個案(test cases)在這個時候就派上用場了,測試除了可以找出程式中缺漏的部分,並提供全部使用這個錯誤代碼的部分。除了網羅錯誤之外,從參考報告中你可以大概抓出這個程式的雛形。

不過,如果你的測試沒有囊括全部的程式,你卻以為全部都測試了,那你之後可能會遇到一些麻煩。所以,記得一定要做一個完整的測試!

問題五:不同模型之間的路徑不明確

有些程式寫得非常好,但是卻有一些不尋常地跳躍。模型之間的排序和堆疊順序很重要,整個程式的邏輯應該盡可能的平順。你必須要能看到所有模型和他們所解的的問題。寫程式的時候,不應該會了好看而獨立某些模型,應該考慮到他和其他模型的連接,以及是否能銜接下來的程式。

問題六:創造演算法

工程師常常會覺得自己正在建立新的演算法來解決問題。幾乎所有的問題都有對應的演算法可以用,而且可以互相組合,就可以解決你的問題了。像是 Dijkstra’s algorithm、levenshtein distance、voronoi tessellations 等等。兩種情況下,你才需要建立新的演算法,一,你不知道有可以用的演算法,二,你在寫博士論文。

想像你在明亮的森林中沿途留下麵包屑,因為當你回程的時候,森林已經一片漆黑。

總歸一句話,你的目標就是讓程式的結構竟可能的簡單易懂。縮短語意模型和語法模型的距離,盡可能地提供線索,讓任何人都可以看透你當時的想法和思路。

這些技巧聽起來很簡單,實際上卻很難,加油吧,兄弟們!

文章來源(原):https://medium.com/on-coding/why-your-code-is-so-hard-to-understand-83057c115a2b

文章來源(台灣):http://buzzorange.com/techorange/2014/11/20/why-your-code-is-so-hard-to-understand/

發表留言