不知各位對這標(biāo)題是否困惑?也不知各位知不知道我最近的事情?
我直接說,因為我打算離職,並且踏入服務(wù)業(yè)。
很奇怪的決定吧?原因,有,但我只是想跟各位解釋一下標(biāo)題而已,所以詳細(xì)這裡先不說。
繼上一篇(第四集),這次也是要介紹關(guān)於工程師的熱門書籍。
雖然不知道還會不會再踏入程式業(yè)界,但我並沒有放棄程式,最大的原因是我對程式的熱情出自於一種創(chuàng)作。
我希望未來能繼續(xù)創(chuàng)造故事,最高級是遊戲,次要拍戲,最後寫作等方式。
最希望,是我這夢想能夠延續(xù)。
--------------------------------
作者,Robert C. Martin,自稱Uncle Bob(所以我以下用Bob稱呼他)。
撰寫的一連串關(guān)於clean code的書籍,已被博碩出版社翻譯出四部(經(jīng)典)。
而我的閱讀方式是以出版日期決定,所以先讀這本,無瑕的程式碼:敏捷軟體開發(fā)技巧守則(中文名稱)。
第一次接觸到clean code是在第二家公司時,主管很細(xì)心抽空教導(dǎo)我,也是他推薦我"設(shè)計模式與遊戲開發(fā)的完美結(jié)合"(可參考上一篇第四集)以及Robert C. Martin的書籍。(或許之後會寫一篇關(guān)於我出社會的故事)
一開始我其實擔(dān)心一件事,因為原文是外文,加上這是關(guān)於程式的書籍,深怕出版社會不會翻不出個所以然。
但事實證明是我擔(dān)心過度了,雖然我沒看過原文書,不過我能讀懂(就差經(jīng)驗,看裏頭範(fàn)例就可清楚跟高手的差距;雖然以前有被同事嗆說"阿你不會看原文喔",也經(jīng)由這次讓我對博碩出版的程式書籍有信心)。
不過,我必須老實承認(rèn),過去接觸到clean code的觀點......非常的皮毛!
而且在業(yè)界的時候,我很不常用,本書也有提到過,公司規(guī)則也必須遵守,但是是建立在clean code為前提(假設(shè)把此書內(nèi)容當(dāng)作教條)。
可惜,在業(yè)界中,我看到的是各個自己的style(包含我自己),頂多一部分有遵守(比如我第二家的某主管),一部分沒有。
這就像我沒辦法控制別人心靈的感覺,除非把clean code(當(dāng)然還有TDD原則)列入公司規(guī)定,或許才有辦法吧(不安地笑)。
那我提幾個令我驚訝的地方吧(全說你們就不會想買啦呵呵,請支持正版)。
(1)宣告:我所接觸過的,都跟書裡反著來哈哈哈。
因為本書強(qiáng)調(diào)寫程式就像寫散文,讓人能夠順勢由上往下看(除非你看得意猶未盡)。
而以前我所接觸的,甚至學(xué)校,都是宣告通通放最上面,頂多function才按照執(zhí)行順序。
但在Bob的理想中,假設(shè)有一個function,那跟這function有關(guān)的變數(shù)宣告就要放在上面(除非前面已經(jīng)使用過,那就不必再移動)。
意思就是,理想狀況為"變數(shù)->函式->變數(shù)->函式......"(除非沒要宣告變數(shù)啦)。
不知各位是否一開始就這樣寫,還是你跟我早起一樣被"把宣告通通放在最上面"給荼毒了呢(笑)?
(2)封裝:我必須老實說,以前我連封裝是甚麼都不知道,只會用,但不知道那叫封裝,就很像牛頓定義地心引力之前,人們只知道東西會掉下去。
而最初知道是藉由面試,雖然以前面試被打槍的很慘,但"不經(jīng)一事,不長一智",現(xiàn)在反倒要感謝他們,讓我能夠感觸那麼深(你確定不是記仇嗎,笑)。
重點來了,若你是在業(yè)界的程式設(shè)計師,你應(yīng)該會很常聽到一句話,"如果是只執(zhí)行過一次的程式碼(指令),不需要封裝起來"。
不過,看完clean code後,我開始感覺到,封裝是一件非常有挑戰(zhàn)性的任務(wù)。
有時候一句話,甚至沒重複過,也需要封裝起來。
雖然我還沒那麼成熟,所以我目前的想法是,你能解釋的就把它封裝起來吧(笑)。
function名稱,或class名稱,臭長沒關(guān)係,但要解釋的完整(當(dāng)然不是單純把程式碼每行做的事翻譯成名稱)。
最重要的是,若耦合性太高(甚至只要有耦合這狀況),也要做分類,這也是為了未來好改(也是這本書重要其中宗旨)。
(3)if/else and switch:這在"設(shè)計模式與遊戲開發(fā)的完美結(jié)合"有提到,也是常見又容易造成容長的原因,但"設(shè)計模式與遊戲開發(fā)的完美結(jié)合"中是用模式介紹,這裡比較像是"通用"方式解釋。
我覺得你應(yīng)該猜出我要說甚麼,當(dāng)然是改掉阿,但,說的容易,好改嗎?
以書中Bob的經(jīng)驗,if/else,switch,雖然能改盡量改,但還是會存在於專案。
我對這樣的經(jīng)驗解釋成,很難,但我們重點不是徹底讓他們消失,而是建立於封裝性以及剛剛提到的未來好改性。
我舉個最簡單的例子,switch應(yīng)該是判斷類型中最單純的,我把它當(dāng)成狀態(tài)處理。
而最簡單的改法是,建立一個介面(可以先建立父介面等你自行判斷),此介面當(dāng)作行為用,而它裡面的內(nèi)容就是原本switch裡的其中一種狀態(tài),而使用它的就要implements。
不能這樣做的狀態(tài),多的事呢!那是甚麼,請看書吧(我不太希望這些都由我說,看書最準(zhǔn)確也最實在)。
(4)不斷的磨練:提出這個,並不是只要各位在私下時間繼續(xù)研讀程式相關(guān)的知識這意思。
而是指,你寫過的程式(或稱你負(fù)責(zé)的),就算是在業(yè)界的,也必須保持重複閱讀,用意在於不斷挖掘更乾淨(jìng)的方法。
恩?蠻有道理的阿,阿你講這廢話幹嘛?
分享我的例子,假設(shè)一個產(chǎn)品已經(jīng)通過測試,甚至上架了,我都會被勸不要動它,以免影響穩(wěn)定性。
嘿~不知有沒有人跟我一樣,形成心有靈犀一點通呢(笑),所以若會動的時機(jī),要嘛出Bug時,要嘛"加,改,刪"功能時。
但,不虧是一生奉獻(xiàn)給程式的男人,Bob,他有一套方法。
第一,鎖定目標(biāo)。
第二,加樣本(新code),但不能影響到原本程式的,並且漸漸完整。
第三,抓範(fàn)圍,這或許在你改之前就要先看了。
最後,你懂得,取代跟刪除。
看起來簡單,但我遇過被禁止的狀況,因為他們會以為那是廢code(解釋後又被勸阻),所以......就掰掰啦(苦笑)。
另外磨練的方法,我再舉裡面提到的一個,把你的code無私地給別人看(若是業(yè)界的,就分享給同事),切忌,這不是要你當(dāng)紅。
這本書中也讓我發(fā)現(xiàn)一個有趣的開發(fā)模式(指行為上),就是結(jié)伴模式。
一人寫,一人看,你沒看過對吧?因為我也沒看過,所以看到這方法時超驚訝,難道老闆不會認(rèn)為這很浪費人力嗎?
有啊,Bob也說,所以這情況就真的很少見。
不過我經(jīng)歷過的,倒是有一種替代模式,就是你的(程式)上司來看你的code,並且提出建議,這樣也可以達(dá)到互相成長的效果,雖然通常是我獲益比較多拉(笑)。
不然就是大家找時間,公開討論你的code(很像公開處刑吼,笑)。
(5)註解:你會加註解嗎?那你敢不加註解嗎?
就很像一個已經(jīng)找到舒適圈的人,要他離開舒適圈的感覺(關(guān)於舒適圈是否要一直挑戰(zhàn)逃脫這課題,有空再談)。
Bob強(qiáng)調(diào)我們應(yīng)該用命名(泛指全部需命名的狀況)就代表一切,若你已經(jīng)達(dá)到這點,那註解就不用加了?
沒沒沒沒沒,是我們應(yīng)該加更有意義的東西,那是甚麼?
我舉個例子,比如若我將null傳入某function,那它會return甚麼(資料等)?
其實Bob也有提到過,應(yīng)該要避免傳入null,但如果還是有的話,嘿嘿,就可以寫註解啦~寫下(以剛剛例子)傳入null後會return甚麼。
還有很重要的一點,不要註解只是單純做翻譯(或拆字)。
比如我宣告一個變數(shù)為playerCount,註解(中文)就打"玩家數(shù)量",那你乾脆不要打算了(笑)。
我並不是在笑這麼做的人,以前我也犯過錯,所以,沒錯我在嘲笑自己(再笑一次)。
還有需要注意,若作品未來有改動,特別是改動到跟你加註解有關(guān)的地方,你就必須重新審視,不然這註解非常有可能變成垃圾(包含備註解掉的code)。
(6)傳入:所謂事不過三,剛好這也能套用在這上。
都沒傳入,厲害。
傳入一個,正常。
傳入兩個,警惕。
傳入三個,快逃......沒有啦,給我改啦(笑)。
改的方法很多,但絕不是放在一個陣列中草草了事(弱型程式可以輕鬆辦到的事情)。
比如將某變數(shù)變成某class的全域變數(shù),或靜態(tài)變數(shù),這就只能看你認(rèn)為當(dāng)下哪個適合了,但簡單來說是這樣。
(7)tramp data:你知道所謂的tramp data嗎?
以前我犯過的,但......很少啦。
我用例子說明,比如int a = aClass().getA().getB().getC() ......
如果那麼臭長,老方法,將它封裝吧,被封裝的名稱你要多臭長都沒關(guān)係。
(8)命名原則:這地方跟前面重重相關(guān),但對我來說,根本是考驗我英文嗎(苦笑,除非有團(tuán)體是用中文寫code,www~)。
當(dāng)我看這本範(fàn)例時,時常卡住。
第一,我根本無法明白高超的Bob為何要這樣封裝。
第二,命名,讓我第一次卡(看不懂這封裝要幹甚麼),也讓我最後一次卡(為什麼這樣命名就可以了?)。
不過這讓我想到以前一個美好時光,當(dāng)時還在第二家的時候。
為了讓命名呈現(xiàn)完整性,所以(我負(fù)責(zé)的)一堆名字,又臭又長,曾經(jīng)主管們也為這件事嫌過。
關(guān)於命名,我認(rèn)為的優(yōu)先順序是,1.完整性,2.清楚性,3.統(tǒng)一性。
像裡面範(fàn)例,Bob也有幾個命名長成這樣"XXXXXandXXXXXX"。
雖然只說到這樣會讓人感覺沒保持單一性,但其實不是(詳細(xì)就建議各位看書囉)。
所以我才會認(rèn)為,完整為先,再來清楚,但這兩個是必須同時存在的,只是如果我思考如何命名,順序會變成這樣。
統(tǒng)一性就是,照公司規(guī)定啦,最簡單的方法是主動找人討論命名。
再來有個有趣的現(xiàn)象,比如我在第二家時,我們有一個攻擊招式,中文為火球西瓜。
那你猜,那個class命名是甚麼?我記得是fireWatermelon。
很直接很清楚?。坑猩觞N奇怪嗎?
那,如果企劃未來把這招換名字呢?你要把class名稱跟著改掉嗎?
繼續(xù)延續(xù)剛剛的故事,我們之後換了企劃,要求我們大改招式,包含名字。
那我們之後有改class名稱嗎?嘿嘿,沒有......
回到重點,我們不該替任何變數(shù),取跟遊戲強(qiáng)烈關(guān)係的名稱,不過比如常用的"攻擊","防禦"等倒是不用,這標(biāo)準(zhǔn)我可以提供一個參考,就是不會更動(不會更動這不能企劃說了就算,以我的經(jīng)歷,太容易被雷了,要看整理遊戲產(chǎn)業(yè)的歷史跟文化,所以要說是共通名稱也可)。
那要怎麼命名呢?用剛剛例子,比如取名為"帶屬性的貼地遠(yuǎn)程攻擊",如何?這還只是中文喔,翻譯成英文應(yīng)該更長(你們自己翻吧,笑)。
那火屬性這意義怎麼辦?我先反問你,如果今天改屬性了呢?基本上應(yīng)該會先繼承某父類別,再幫每種屬性建一個class,所以(中文)便是"火屬性貼地遠(yuǎn)程攻擊"吧。
命名規(guī)則還有很多,而我再舉一個,比如你看前輩的code,很常出現(xiàn)比如"string sName"。
那是以前工具還沒那麼發(fā)達(dá),甚至要自己手動翻找code的時代才用的方法(真正命名前加狀態(tài))。
但現(xiàn)在工具已經(jīng)發(fā)達(dá)(又免費),不需要,甚至是匈牙利命名法(作者蠻不建議這方法命名)。
呼~光是這本就打那麼多了,這本跟等等介紹,同作者同系列的差別在於,這本只介紹寫code的方法。
那不然呢?還有甚麼可以介紹嗎?嘿嘿,那請你繼續(xù)看下去吧。
--------------------------------
同年(2013),博碩再度出版Bob的其中一個著作,無瑕的程式碼 番外篇:專業(yè)程式設(shè)計師的生存之道(中文名稱)。
我敢保證,這本看完,如果你有勇氣,將會在業(yè)界(以臺灣為例)掀起一場革命。
愛的前提是快樂,快樂的前提是自由,自由的前提是勇氣,這是我最近體會到的,也是我現(xiàn)在的理念之一。
進(jìn)哲學(xué)之路之前,我認(rèn)為很多東西是可以分開的(現(xiàn)在還是有些會抱持著這樣的觀念),但後來發(fā)現(xiàn),不是,比如正義勢必帶來榮耀這樣的說法。
這本書也可以說是Bob的心路歷程,他以自身為例子,寫下很多與世不符,卻是專業(yè)之道的理念,我認(rèn)為他很有勇氣,所以才會想起我那理念。
最讓我從書中學(xué)到的精隨是"說不"的勇氣,雖然裡面也有提到怎麼"說是",但反而讓我認(rèn)為,怎麼還是停留在上一章的感覺(難怪"說不"會放在"說是"前面,笑)。
其中幾個理念,雖然跟我遇到的情況不相同,但,我認(rèn)為道理是一樣的!
(1)預(yù)估焦慮:書中解釋,"評估也通常存在著巨大的變數(shù)。其次,因為『不確定原則』的存在,所以不可能透過反覆推敲而實現(xiàn)早期的精確性。需求是一定會變化的,所以追求那種精確性是白作工的。"
我覺得亮出這招,肯定會傷害許多老闆以及上司的心,但卻又找不到藥膏,因為這是沒辦法掩蓋這事實(就算口才再強(qiáng),我也認(rèn)為是詭辯)。
Bob也有提出建議,假設(shè)我知道這任務(wù)(或案子)已經(jīng)沒辦法達(dá)到先前提出預(yù)估的時數(shù),就應(yīng)該馬上說(通常這時間點應(yīng)該是比預(yù)估時數(shù)早的)。
但這麼做的話,新手可能會問,會被罵嗎?會被怎樣嗎?
我親愛的讀者,如果你不敢說,誰能幫你?以我的經(jīng)驗,如果時間到才說,下場會更慘。(會不會有反例呢?比如書中曾經(jīng)提過一個很搞笑的故事,Bob曾經(jīng)做一個市場用app,好不容易延長時間並且完成,但案子早就被討論而捨棄掉了,所以,看命運囉~記得每天燒香拜拜哈)
(2)遲來的模糊性:你相信心電感應(yīng)嗎,我告訴你,我不相信,也認(rèn)為不可能。
假設(shè)我是老闆,我要你(假設(shè)你是程式設(shè)計師)做一個市場調(diào)查app,沒了。
恩?你應(yīng)該會想,不,是肯定會罵我,你腦袋有病是不是?你應(yīng)該先跟企劃談,企劃再把詳細(xì)的內(nèi)容給我才對啊。
對,這只是很~簡單的例子,重點是,做到甚麼程度?不先說清楚,只會造成"雇主失望"的下場,會特別記得這單元,當(dāng)然是我經(jīng)歷過,剛好我第一到第三家連線都有啊(苦笑)。
(3)危機(jī)中的紀(jì)律:經(jīng)歷過前面說不得勇氣,那還有甚麼值得讓我們了解何謂專業(yè)呢?
專業(yè)在這本書裡面,不是說你會做多少(功能),甚至也不是在說技術(shù),而是一種精神理念。
除非你懷疑你的做法(若你沒勇氣的話,老實說我認(rèn)為你會跟我以前一樣,容易被搖擺,也不知道是哪邊有問題),不然你應(yīng)該堅持,因為你的初心是要讓作品好。
我認(rèn)為我還沒到那功夫,但Bob一定有,因為他也是一名TDD理念保持人。
比如,TDD是先想好怎麼測試,再寫測試code,最後寫主程式。
若工時不長,老闆或上司要求你不要用TDD的做法,他們認(rèn)為這樣可以縮減時數(shù)。
但,重點來了,為何一開始決定實踐TDD?不就是為了作品穩(wěn)定性嗎?不就是為了減少其他人的麻煩嗎?
要我改掉簡直是過河拆橋,甚至把島整個拆了。
所以,若你願意遵守這原則,你應(yīng)該先說不,那當(dāng)然還是不夠的。
你要跟上面的人尋求從容中道,那如果還是沒辦法呢?
堅持你的理念,再說一次不吧!
其實看完這本書,以我的經(jīng)驗來分享常見的問題順序。
預(yù)估時數(shù)>出Bug>不會做>要求更清楚的說明。
很多人會再預(yù)估時數(shù)的時候卡關(guān),而且這問題也會不斷發(fā)生(只要你再別人底下寫程式的話)。
你也一定會很常被催眠(次要催促,在業(yè)界),比如上司跟老闆說:「這很簡單啦,大家都會啦,不用花那麼久啦。」
但,你必須以你的角度,勇敢的說出來,我以前也是傻傻聽話,做不出來,只會回話"我會再努力",然後愈來愈糟(至少身體方面),也瘋狂加班。
Bob也有提出幾個計算方法可以參考,但絕不會比實際做而花的時間準(zhǔn)確。
而我補(bǔ)充一句,跟別人解釋的時候,需保持理智(我認(rèn)為是心情與口氣平靜,不做任何表情),我可以推薦你一本書"我想跟你好好說話"(等我讀夠多書我再一併介紹,模式應(yīng)該跟前面幾集一樣),雖然我也遇過死木頭,因為對方心中有答案,只要你不照他的做,他就認(rèn)定溝通失敗,而且會把錯推到你身上。
(4)專注模式:Bob介紹這點時,讓我想到"黑子的籃球"的"ZONE"模式(雖然還是有些不同啦哈),讓我大腦陷入一個超中二的想像中(笑)。
曾經(jīng)我也進(jìn)入過這模式,非常的爽快,code可以一口氣打完,也幾乎能夠執(zhí)行。
但Bob卻要我們小心這時候的行為,甚至建議我們乾脆不要進(jìn)入。
因為這時候打得code多半都會錯誤(不遵守clean code,甚至不考慮未來的後果)。
我曾經(jīng)在第二家公司時,我同事時常進(jìn)入這模式,也曾經(jīng)因為打擾他而被罵過。
不過自從了解這模式的風(fēng)險後,我反而感到自我安慰,也覺得應(yīng)該更時常警惕自己。
所以若下次你也遇到這種情況,比如自己陷入那模式時,有人打擾你,不要生氣,甚至可以向他感謝(苦笑)。
--------------------------------
我這輩子,我認(rèn)為我讀書很少,更何況是程式相關(guān)書籍。
大學(xué)時,求過就好,所以沒上進(jìn)。
出了社會,才發(fā)現(xiàn)要學(xué)的很多(比如設(shè)計模式等,特別是專業(yè)術(shù)語)。
開始後悔大學(xué)不夠努力,甚至?xí)R學(xué)校怎都不教。
但,"學(xué)習(xí)是一輩子的事",不只不該怪罪別人外,我也不應(yīng)該朝"我很笨"的方向想,而是朝"我能學(xué)得還很多"。
也不要認(rèn)為學(xué)習(xí)是件羞恥,反而應(yīng)該感到自豪。
我現(xiàn)在很慶幸我遇到這麼多好書,也很自豪我有勇氣去讀(因為我遇到太多人把沒時間當(dāng)理由了)。
結(jié)合上一集提到的程式書,給各位一個閱讀建議。
圖說演算法(雖然我覺得我看的那本很爛,你可以找別人寫的)->設(shè)計模式與遊戲開發(fā)的完美結(jié)合->無瑕的程式碼:敏捷軟體開發(fā)技巧守則->無瑕的程式碼 番外篇:專業(yè)程式設(shè)計師的生存之道。
以前我曾想過要不要給各位寫程式時應(yīng)該遵守的順序,但我認(rèn)為,這些都是相輔相成的,所以,應(yīng)該是全部都要(小孩才做選擇,笑)。
偉大的前輩,Uncle Bob也說過,專業(yè)的程式人,應(yīng)該不斷索取新知識,重點不在被淘汰,而是靠閱讀增廣見聞,增強(qiáng)自己的想像力。
而我最想誇獎的是"無瑕的程式碼 番外篇:專業(yè)程式設(shè)計師的生存之道",譯者也有提到,此書的眾多觀念,不只不懂程式的人也看得懂,這本書的精神甚至可以廣泛用在各職業(yè)上。
重點,你有勇氣嗎?
說來好笑,我的勇氣雖然是我的導(dǎo)師給的,但真正讓我感到我是有勇氣的,是我自己曾經(jīng)堅持我的想法,並且行動。
之後離開程式業(yè),不只為了成為理想的大人,更是考驗自己對程式的熱忱,若我沒花(私下的)時間寫code的話,我就能更明確知道我要的是甚麼。
雖然我目前心中有了答案,但,"只想沒用,要做才行",不是嗎?
--------------------------------
目前企劃的專案依舊是以前常提到的"傳頌之物外傳",標(biāo)題目前命名為"飛向起點的種子"。
遊戲模式應(yīng)該是單純的文字冒險,重點是裡面的code,我要嘗試以以前讀到的書,那理想的方法實踐。
劇本寫完後應(yīng)該也會放在這帳號上(所以就算沒法做出遊戲,還有小說版可提供,也告訴各位我沒營利的想法),這一條路很漫長,重點我有好多次,好長一段時間,逃避這案子(因為我不斷考慮利益以及會不會違法之上)。
但我下定決心,脫離舒適圈(轉(zhuǎn)行),走上修羅之路(服務(wù)業(yè)),我就馬上想到,那以月牙灣(除原唱外,我蠻推薦大陸歌手哦漏版本,對我來說,只要沒唱出那種思念的感覺,都是爛作)的心情,還在腦海中漂浮的故事。
我期待自己的成長,我期待作品的誕生,或許你們看我眾多作品(寫作)都是喜劇(搞笑),但我一開始是悲劇起家阿(但那小說已刪除,目前也沒想要重新啟動,現(xiàn)在唯一能稱悲劇向的是血命,但對我來說那主要是以諷刺為主)。
期待各位能夠成為(自己認(rèn)為)理想得大人,我們一起加油,我們都能夠擁有(使出)勇氣。