還記得周星馳主演的電影《國産淩淩漆》有一段讓人捧腹的情節, 在淩淩漆和司令對戰時刻, 達文西半路殺了出來, 揚言要讓司令嘗一下他新發明的集10種緻命武器于一身的「要你命3000」的威力, 傳說這是勝過任何武器10倍威力的殺人利器,然而,還沒等武器開鋒,司令一槍就把達文西給打殘了。周星馳的電影就是這麼無厘頭,但通過這個情節來仔細觀察我們的世界,會發現一種規律,我們人類生産的任何工具,都是針對解決特定問題的, 換句話說, 很多工具功能都是單一性的, 多功能的事物似乎沒有那麼容易流行開來,就像文西發明的要你命3000一樣。 其中例子舉不勝舉
洗髮乳、沐浴露、潔面乳雖然都是清潔用品,但都是有各自的作用
小說、技術書籍、課本雖然都是書籍, 但是都是針對不同領域的
籃球鞋、足球鞋、跑鞋雖然都是鞋子,但都是為不同類型的運動設計的
汽車、貨車、客車。。。
客廳、廚房、衛生間。。。
就連一部手機中的app也有不同種類分别起着不同的作用。
存不存在這樣一種工具, 它內建了所有或者大量的功能, 隻要使用它就能解決掉我們需要解決的所有的問題?手機和電腦或許算是這類工具的典型代表,能幫我們做很多事情 。 然而,事實上具體替我們做事情是裝在它們内部的軟體 , 而這些軟體的功能是單一的, 微信用來聊天, 新聞用戶端就來了解實事, 支付寶用來付錢、淘寶用來買東西,是以從另一種角度來說, 手機或電腦隻是一個功能的集裝箱, 用來解決我們問題的還是這個集裝箱中的工具。
是以,從中我們可以發現規律 ,我們人類似乎比較偏好于歸類和分解, 把某一個大問題分解歸類成不同的小問題, 然後發明出針對解決小問題的工具。拿上面舉的例子來說, 本來清潔用品隻用肥皂就可以了, 現在卻被分解成了洗頭發的、洗臉的、洗身體的種各五花八門的清潔用品; 我們要學習知識,知識卻又會被分解成不同的知識種類,國文、數學、實體、化學等等。我們人類的社會為什麼會發展成這樣的形态? 我們總是善于組合使用各種不同的功能單一的工具來解決特定的問題, 而不是使用一個功能龐大複雜的工具中的其中幾項子功能來解決特定的問題。究其原因,是因為我們人類親「簡單」厭「複雜」,因為我們人類的智商還不夠高,一個人無法掌握整個世界的所有規律, 是以隻能将事物分解和單一化, 然後不同的人掌握和使用這個巨大集合中的其中一部份。
萬事萬物都逃脫不了這種規則的制約,包括虛拟的計算機世界。 在軟體的使用者眼裡, 一個軟體由不同的功能組合而成, 比如說微信,它可以聊天、看朋友圈、付錢、看公衆号文章。然而在程式員眼裡, 這裡的任何功能還可以再一次細分, 比如說看朋友圈, 在實作層面大概有以下幾個流程,用戶端從網絡請求資料、将資料轉換成界面、顯示文本、顯示圖檔等等,而且這些功能還可以再次分解, 一層一層下去直到分解成一行一行的代碼為止。 從某種角度去了解,一個程式有一萬行代碼, 那麼就意味着它由一萬個功能項組成, 然而,這顯然太過于複雜的不利于我們大腦去了解了, 然後就出現了函數,用函數對這些細小的功能來進行整理劃分,使得代碼易于了解, 這就好比圖書館有這麼多書都會被放在不同種類的書架了,因為這樣易于讀者尋找。 然而, 當代碼量過大, 功能過于複雜時,以函數為機關的代碼也會出現了了解上的困難,于是接下來又出現類、包(名稱空間)等更進階别的代碼歸類工具。就像一個大型圖書館, 書籍會按照書架、區域、樓層等不同的方式來劃分書籍的放置區域。 而且這些書籍并不是被随意放置的, 計算機的書籍不可能出現在醫學類的書架上,兒童讀物的書架也不可能被放在成人類書籍區域,因為這會大大的影響讀者尋找書籍效率。
代碼的組織和圖書管書籍的放置在道理上是相同的, 隻是具體實施起來要複雜靈活的多, 其中大緻的規律就是
一行代碼隻有一種意思。 反例:定義一個變量, 即用來放置姓名,又用來放置性别。
一個函數隻做一件事情。 首先,函數名稱的含義一定要和代碼實質做的事情保持一緻; 其次,切記不要讓一個函數實作過多的功能,比如有一個删除使用者資訊的函數, 而且資訊又關聯到許多的資料, 如登入記錄、登出記錄、訂單資料、權限資料等等, 可能删除所有這些資料需要上百行代碼, 那麼千萬不要把所有的代碼放在一個函數裡,甯可把删除各類資料的代碼放在各自的子函數,然後通過删除使用者的函數調用這些子函數來實作具體的操作。
一個類和一個包(名稱空間)也隻做一件事情 。 這其中的要點就是對功能的細化與抽象, 一個類中有若幹個函數, 每一個函數分别實作單一的不同的功能,而類就是更高層面的單一的功能項, 就拿上面删除使用者的例子來說, 其實我們完全把删除使用者這一個操作組織成一個類, 這個類的功能就是删除使用者, 而類中的函數分别是删除使用者登入資訊、删除使用者登出資訊、删除使用者訂單、删除使用者權限等等,問題的關鍵在于代碼的邏輯一定要順暢 , 易于了解 。 同樣,包(名稱空間)就是類級别以上的歸納方法,從更高的層面上去了解, 它的功能項也必須是單一的。 如同圖書館内, 不同的書籍區域就可以看作是程式設計中的包,如計算機區域、醫學區域、國外文學區域。 而區域下面的書架就可以看作是類,比如說計算機區域下Java書籍的書架、.net書籍的書架、作業系統書籍的書架 等等。
想要一個項目易于了解易于維護, 就需要有清晰的脈絡, 小水流彙聚成溪、溪彙聚成河、河彙聚成江、江彙聚成海, 一切都要井井有條。所謂軟體工程,就是要将代碼合理的組織在一起,克服複雜多變的需求, 使之能清晰、高效、有條不紊的運作。 最後還是那句話:人的腦子太笨了, 複雜的東西了解不了, 我們要使用手段和技巧将問題變的簡單再簡單,分而治之, 才能高效的解決。
知乎:https://www.zhihu.com/people/aspwebchh
github:https://github.com/aspwebchh
email: [email protected]