2024-04-23|閱讀時間 ‧ 約 46 分鐘

書摘《程式設計守則》


這些守則是怎麼來的?

其實很多時候我們並不需要去解決什麼大問題;就算想解決,也不是現在呀!那種能夠解決大問題的做法,對於我們所遇到的小問題來說,往往都是比較平庸的解法 —— 不但用起來比較複雜,理解起來也比較複雜,而且還有可能把更多的 bug 隱藏起來。 p. xi

當然,我們大多數的新程式設計師,都曾犯過「太早去考慮通用性」的錯誤,而這些守則確實可以幫助他們,避免一在犯下這樣的錯誤。 p. xii

如果你不認同這裡的守則,該怎麼辦?

至少它對「我們」來說確實是正確的,不過對「你」來說,的確有可能是錯誤的做法。理解這其中的道理,可以有助於你進一步理解,強化你自己的程式設計哲學。 p. xv

守則 1 | 越簡單越好、但也不能太過簡單

任何問題的最佳解法,就是能滿足問題所有的要求,其中最簡單的那個做法。最好的程式碼,就是最簡單的那段程式碼。 p. 1

比較簡單的程式碼,總是比較傾向於採用團隊裡每個人都知道的概念作為基礎;它不會輕易引入一些需要重新思考問題的新方法或新術語。 p. 4

這也是 Ubiquitous Language 想做到的事。

如果你能寫出很容易看懂的程式碼,而且很快就能派上用場,那你所建立的應該就是最簡單的程式碼了。 p. 4

程式碼簡單一點確實很不錯,但它終究還是要能把問題解決才行。 p. 4

有時候簡化問題比簡化解法更重要 p. 7

實際上不管是什麼東西,到最後終究會遇到東西滿出來放不下的溢出 (overflow) 問題。為了解決這種極端的臨界狀況,結果總是會讓我們引入太過於複雜的解法。請不要為了解決問題中最嚴格的情況,而掉入這樣的陷阱之中。你應該針對實際需要解決的部分,提供一個簡單的解法,而不要為了更廣泛解決所有的情況,反而提供更複雜的解法;務實而簡單的解法肯定是比較好的,如果無法簡化你的解法,或許你可以先嘗試簡化你要解決的問題。 p. 10

有些產業確實對數字很敏感,像是金融業,但不是每個產業都是如此。這一段讓我特別有感,過去曾有一些會議,大家都在討論極端狀況該怎麼處理,讓我很納悶,這些情況會很常發生嗎?無法靠流程或使用方式去控制,非得要用程式自動處理?

這一切並不是因為程式碼本身,而是因為我們選擇了更好、更簡單的演算法。 p. 12

簡單的程式碼總是比較容易閱讀 —— 尤其是那種最簡單的程式碼,根本就可以直接從上面一路往下讀,就像在讀一本書一樣。 p. 12

我跟作者想法是一致的,但實現手法上,我偏好使用抽象層級相似且更接近 domain 的 function 來敘事。

刪除重複程式碼其實是要付出一些代價的 —— 如果只是少量的程式碼或單純的想法,最好還是保留原本重複的版本就行了。這樣一來,程式碼會比較好寫,而且也會比較容易閱讀。 p. 14

個人是認同不需要移除全部的重複程式碼,但書中的例子之所以降低易讀性是因為 function 的命名不好 XD

「複雜性」這東西到最後一定會扼殺掉你的專案。 p. 14

所謂有效的程式設計,其實就是想辦法讓那些無可避免的情況越晚發生越好。在添加功能、修正 bug 時,一定要盡可能少添加一些複雜性。 p. 15

守則 2 | Bug 是會傳染的

程式設計有個真理,那就是越早發現 bug,修起來越容易。這個說法通常是正確的 ...... 不過我認為更正確的說法是,你的 bug 發現的越晚,修起來就越痛苦。 p. 17

更別說 Intel 在 x86 指令架構留下的 bug,讓 AMD 在設計 x86 相容處理器以及微軟開發作業系統時,連 bug 都要相容處理,夠痛苦了吧。

這類的測試工作其實是很昂貴的。針對程式碼寫出相應的測試,所要花費的時間很有可能與寫程式碼本身所需的時間一樣多。 p. 19

以自己的工作經驗,這句話本身沒錯,甚至寫測試的時間還要更多一些,但後續的報酬我認為是划算的。

換個角度來說,你當然也「可以」盡量去建構出更容易進行測試的程式碼。 p. 20

這其實是「測試驅動開發」這套做法的其中一個隱藏優勢 —— 比較容易測試的程式碼,往往寫起來比較容易。如果你一直有在考慮如何測試你所寫的程式碼,最終你就會寫出比較簡單的程式碼。 p. 26

我覺得這才是 TDD 的重點,TDD 是開發方法,不是測試方法,而且更好的說法是,盡可能去建構出更容易「使用」的程式碼。個人很少使用正統的 TDD 方式寫程式,但卻是時時在考慮如何測試自己寫的程式碼。

就算你的整個專案只有你自己一個人,你「以後」所寫的程式碼還是有可能會投來調用你「現在」所寫的程式碼 —— 那個未來的你,到時候很有可能會變得像個陌生人一樣。 p. 27

前陣子回頭看 ComicSurfer 的程式碼,確實有種「這誰寫的啊?」的感觸。

前來調用「你」程式碼的人或許真的犯了錯,但「你」所處的位置,確實才是更容易發現錯誤的位置。 p. 28

程式碼給出「未定義」的結果,這本身其實就是介面設計不良的一種跡象。 p. 31

讓程式碼更容易進行測試的大多數技術,多半也會讓程式碼變得更容易編寫 —— 這是因為我們必須針對所有的使用情境,編寫出相應的測試,而這往往會促使你,想盡辦法去簡化出比較少的使用情境。 p. 34

或是寫出更多需要維護的測試案例 Orz

守則 3 | 取個好名字,本身就是最好的說明

東西的名稱,其實是你的第一個、也是最重要的「說明文件」。這是你迴避不掉的東西。它永遠都在那哩,跑也跑不掉。 p. 36

幫某個東西挑名字時,你的目標其實很簡單 —— 名字應該要能概括出這東西的重要之處,並引導那些看到它的人,讓大家知道應該把它想成什麼樣的東西。 p. 36

不要為了少打幾個字,而去簡化名稱。 p. 36

在現代 IDE 的輔助下,我自己的經驗,通常不用五個字母,IDE 就能挑到正確的名稱,只需要按下 enter 即可,短的名稱反而讓 IDE 很難選出正確的東西... 所以我真的很討厭、非常討厭、超級討厭那種無意義的變數名稱

請別忘了,大家去讀程式碼的次數,絕對遠多於去寫程式碼的次數。一班人在寫程式時,很容易忘掉這件事。 p. 36

不要混用不同的約定慣例做法。 p. 38

如果你有一套很一致的命名規則,當你在不同函式或程式碼庫的不同區塊之間傳遞變數時,只要是類似的東西,應該都要有類似的名稱才對。只要是相同的東西,通常就會有相同的名稱。 p. 45

一致性的關鍵,就是設法讓一切都盡可能「機械化」。 p. 45

守則 4 | 先找到三個例子,才能改用通用的做法

這就是問題之所在 —— 你的預測很有可能是錯誤的。如果你很幸運的話,也許並不會錯得太離譜 ...... 不過,你也有可能沒那麼幸運。 p. 52

這其實是一種很常見的模式,因為實在太常見了,以至於那些信仰「極限程式設計」(extreme programming) 哲學的人,特別針對這種情況取了個名字 —— YAGNI,也就是「你根本用不到」(You Ain’t Gonna Need It) 的意思。 p. 52

像這樣花力氣去做一些額外的工作,值得嗎?這真的是時間和精力的浪費呀。... (略) ... 你所花費的這些時間,再也拿不回來了。 p. 53

還可能造成專案 delay

如果只看到一個實際案例,根本就「不足以」預測出通用的解法,因此,過早嘗試去寫通用的解法,其實是不對的。 p. 54

這其實是很容易受挑戰的論點 XD

一但有了三個獨立的使用案例,我們就可以更放心去採用更通用的做法了。不過,你還是要先確定,這樣確實可以讓程式碼變得更容易寫、更容易讀,然後才去進行通用化的工作;而且,你依然只需要考慮自己手頭上的實際案例即可。 p. 57

過早採用通用做法還有另一個不太明顯的問題,就是當我們遇到沒考慮到的實際案例時,想直接套用原本的程式碼會更加困難。這有一部分是因為你所寫出來的通用程式碼通常會比較複雜,因此需要更多力氣來進行調整。 p. 58

這就是過早採用通用做法真正的危險之處 —— 你不但會去實作出一些永遠用不到的功能,而且你所採用的通用做法,實際上還會給你限定出一個難以改變的方向。 p. 64

守則 5 | 最佳化的第一課 —— 別去做最佳化

過早進行最佳化,其實是萬惡之源。 p. 67

這原則來自對秒數斤斤計較的遊戲公司。當有人在沒有任何數據下,就跟你說最佳化多麼多麼的重要,一定要進行最佳化,請別理他。

最佳化的第一課 —— 別去做最佳化了吧。 p. 71

最後再提一點 —— 簡單的程式碼想要變快是很容易的 —— 這就是第二課要講的東西。 p. 71

下面是一條經驗法則 —— 如果你有某些程式碼從沒進行過最佳化,這樣往往不需要花太多功夫,就能讓它的速度提高五到十倍。這聽起來好像有點太過於樂觀,但其實並不會喔。實際上,沒進行過最佳化的程式碼哩,經常都有許多唾手可得的可改進之處。 p. 71

想讓程式碼執行得更快,最重要的就是少做一些事情,而不是用更快的速度去做同樣多的事情。 p. 76

一旦你摘下這些唾手可得的果實之後,接下來就可以繼續去做其他的事情了。請務必抵擋住你心中想要持續進行最佳化的誘惑。 p. 79

守則 6 | 程式碼審查有三大好處

實際上你能從程式碼審查過程中獲得多少價值,取決於你投入多少的時間和精力,以及你如何進行審查的做法。 p. 86

由接受審查者來推動整個審查的過程,通常是不對的做法;審查者很容易就會相信接受審查者所說的話,而不是靠自己真正把事情想清楚。 p. 86

審查者光只是盯著有問題的程式碼,就能運用深刻的洞察力,找出程式碼理的 bug —— 這其實是很少見的情況。 p. 88

如果每個程式設計者都能對程式碼庫不同部份的工作原理有基本的理解,那絕對是件好事。程式碼審查正是傳播這些知識的一個好方法。 p. 88

所有的這一切,都會發生在進行程式碼審查之前 —— 這是我們身為一個程式設計者,自己給自己施加壓力的結果,因為我們希望為自己的工作成果感到自豪,希望我們能夠樂於向同事展示自己的程式碼。這其實是同儕壓力的一種健康的形式。 p. 90

守則 7 | 消除掉各種會出問題的狀況

無論介面設計的多麼巧妙,都無法避免掉檔案開啟失敗的可能性。所以這句話當然不是要消除掉那樣的狀況。這句更想表達的是,如何消除掉那種實際上可以避免的狀況 (或者說是「使用上的錯誤」,像是在關閉檔案之後又想要寫入檔案,或是在物件完成初始化之前就去掉用那個物件理的方法),而不是檔案開啟失敗這類的問題。 p. 93

在編譯階段就阻擋掉這種砸自己腳的行為。 p. 97

其實最好的做法,就是把介面設計成不可能接受錯誤的用法 —— 或是至少讓編譯器能夠拒絕掉那種錯誤的用法。 p. 97

這也是我喜歡強型別語言的原因。

另一個很容易引入問題的設計方式,就是建構出很複雜的物件。 p. 99

下面就是帶有大量參數的函式會有的一些問題 —— 使用起來很不方便,而且隨著時間的推移,還會越來越不方便。這是因為你所要對抗的,是一個政回饋循環。通常最有可能需要再填加參數的函式,往往是那種本來就有一大推參數的函式。 p. 101

我們可以讓編譯器強迫我們自己去採用正確的用法。比較好的做法,就是讓不正確的使用方式根本用不了,而不只是要求大家盡量避免使用而已。 p. 102

大家在嘗試設計出完全防呆的東西時,經常犯下的一個常見錯誤,就是低估了呆瓜的厲害。 p. 110

我們也許可以阻止使用者直接用石頭砸自己的腳,但我們實在很難阻止使用者,用各種怪招來砸自己的腳。我們的目標並不是做出完全防呆的設計 —— 我們只想透過設計讓事情變得很容易做對,而且很難做錯。 p. 111

守則 8 | 沒在執行的程式碼,就是會出錯

程式碼審查比較擅長的是在改動過的程式碼理發現問題,因為那正是審查時所關注的重點。審查的做法並不擅長在沒有改動的程式碼理發現問題,因為只要是沒改動的部分,審查者通常都會直接跳過。 p. 120

一旦接受這段程式碼變成孤兒,它就不會再被執行到;如此一來,你就沒辦法知道它能否一直保持正常運作了。 p. 122

所以最好的做法,就是立刻刪除掉孤立的程式碼。 p. 122

守則 9 | 寫出可收合概念的程式碼

抽象是有代價的,把邏輯分離成一個一個的函式,也是要付出代價的。所要付出的代價,很有可能會超過這麼做的好處。 p. 134

這句話要小心解讀,書中的例子是 map-reduce 的抽象概念,那確實需要付出理解上的代價,但不代表分離成函式都是不好的,當然,錯誤的抽象更會增加閱讀上的困擾。

你的改法會讓程式碼變得更簡單、更容易理解嗎?改過的程式碼更容易把概念收合起來嗎?如果是的話,就可以去建立函式或使用抽象。如果不是的話,那就別這麼做。 p. 136

守則 10 | 把複雜性侷限在局部範圍內

一個有效的策略就是,如果真的無法消除複雜性,那就把它隔離開來。如果某段程式碼內部的細節真的很複雜,但它外部的介面很簡單,複雜性就不是太大的問題。如果要處理這段程式碼內部的問題,你還是必須去應對其內部的複雜性,但如果是程式碼外部的問題,你就沒甚麼好擔心的了。 p. 143

之前寫的那些程式碼具有「二次複雜性」(quadratic complexity):每次添加新的條件,都要添加一段新程式碼來檢查所有的條件,然後還要在程式邏輯相關的每一段程式碼裡添加新的檢查。這樣一來直接的後果,就是這種設計所時做出來的程式碼,所增加的行數會與條件的數量平方成正比。 p. 158

說真的,當加到第二個條件時,我就已經看不下去了,至少我自己不會這樣寫程式,但作者這樣設計例子,真的是辛苦了。

如果每次添加新的功能,都必須在很多地方寫程式碼,那肯定就是一種很不好的跡象。 p. 159

像不像 Shotgun Surgery 啊

如果你所添加的每個功能,都需要在很多地方寫程式碼,那你很可能就是沒有把複雜性侷限在局部範圍內。這樣到了最後,你一定會以淚水收場的。 p. 159

守則 11 | 有比之前好兩倍嗎?

往前邁進的三條道路:忽略、調整、重構。 p. 162

程式設計者在處理這類問題時,往往會有一種很自然的傾向,那就是經常會在錯誤的時間、基於錯誤的理由來進行大改造,但最後所帶來的問題,反而比原本想解決的問題還多。 p. 163

程式設計者其實可分為兩大類。第一類程式設計者會以漸進的方式來思考問題。他們會根據現有的解法,來看待每一個新問題;他們總是希望能調整當前的設計,來解決各種問題。第二類程式設計者會把問題和解法放在一起思考;他們經常會被某種新想法所吸引,總想要去解決系統所有的問題,而不只是解決手頭上的問題,而且他們會盡可能抓住機會,重新開始去做出全新的設計。任何一種極端的傾向,都會變成一場災難。 p. 163

喜歡透過當前的架構,來描述手頭上的問題。比如在描述問題時,比較喜歡使用內部術語,而不是採用問題本身常用的描述方式。 p. 164

如果你反對進行重大變動,其中第一個、也是唯一的一個論據,就只是因為進度上的問題,那你或許就是陷入了第一類人的思考模式。 p. 164

很想要全面改造系統,但最好的理由只是因為「我們真的很需要去清理一下那部分的程式碼」。 p. 164

你之所以提出重新設計系統的論據,主要是基於你打算採用的解法,而不是基於你手頭上的問題。只要不是以問題為基礎的提議,其實都非常可疑。 p. 164

提議要改造系統的理由,主要是因為想採用一些特別耀眼的新玩意 —— 比如改用最新的程式語言、最新的函式庫、全新的程式語言架構什麼的。 p. 164

自己的經驗,還真的都碰過這兩種極端的人。

如果你可以確定改造之後的系統,會比你現在的系統好兩倍以上,這樣的回報就算足夠大,值得讓你去承擔改造過程中難以避免的各種中斷或新的問題。 p. 165

千萬不要貿然去丟掉一些東西,只為了改用稍微好一點的東西取代它;這是一種很糟糕的策略。如果你要丟掉某些東西,一定要用「好很多」的東西來取而代之。起碼要好兩倍以上才行呦。 p. 168

守則 12 | 大型團隊一定要有很強的約定慣例

大家也很容易爭辯說,專案裡每個不同的部分都有不同的需求,所以當然應該區別對待。 p. 169

如果沒遇到真的有人這樣說之前,我大概會覺得這句話很瞎,但我還真的遇到,為了守住慣例,還得跟對方吵上大半天...

如果你真的去混用各種不同的風格 (也就是增加複雜性),當你在不同風格之間切換時,一定會感到痛苦不堪。針對程式碼的不同部分,各自維護不同的風格,絕對不是個好主意。 p. 171

從團隊的角度 (而不是個人的角度) 來看,你的目標應該就是讓整個團隊保持一致。理想的情況下,團隊裡的每個人都應該非常同步,所以大家在遇到特定問題時,應該都會寫出「完全相同」的程式碼。這裡所說的「完全相同」,指的是:相同的演算法、相同的格式、相同的名稱。 p. 177

我覺得很難,但如果在看一段程式碼時,無法一眼就猜到作者是誰,那團隊就算是頻率很近了。

守則 13 | 揪出引發雪崩的那顆小石頭

可是在雪崩半途宣告勝利,就表示那刻小石頭還在。也許到了某個時間點,它又會導致另一場雪崩,到時候被埋葬的程式設計者可能就是你,也可能是其他的人。我們越容易在時間上往回退,就越容易抵擋住只修正症狀的誘惑,越有意願去追溯出根本的原因。這樣可以讓我們更容易找出小石頭,而不只是阻止掉一場雪崩。 p. 185

你可能需要探索一下因果鏈,以找出造成雪崩的那顆小石頭,不過每次在時間上往回退時,最困難的部份是要重現出當時的狀態,而單元測試正好可以幫你解決這個問題。 p. 191

守則 14 | 程式碼有四種風格

這種過於通用的做法,幾乎可以說是一種走火入魔的做法。沒錯,並沒有多出很多額外的程式碼,而且寫出像這樣聰明的東西,確實比寫出簡單的解法更有趣,可是它也變得更難看懂了。 p. 202

「你會不會用簡單的解法來解決簡單的問題?」這個問題正是區分普通設計者與優秀程式設計者的最佳標準。 p. 203

遇到簡單的問題卻寫出複雜的寫法,這種人不但會讓自己的工作變得困難,還會讓團隊裡的其他人工作起來更困難。 p. 203

偉大程式設計者有一種核心技能,那就是在遇到一些看似困難的問題時,他們總是知道,只要能從正確的角度來思考,就有可能找出很容易的解法。 p. 204

最偉大的程式設計者並不是能夠寫出最複雜程式碼的人:而是在面對最複雜的問題時,能夠找出最簡單答案的人。 p. 211

守則 15 | 拔草囉

這個比喻裡的雜草,究竟是只什麼東西呢?它指的就是那些很容易修正,但也很容易被忽略的小問題。 p. 214

修正註解說明並不會在其他地方引起任何問題。而且我確實讓程式碼變得更好了 —— 把註解說明裡模棱兩可的說明修正調,確實有可能會在某個時候,讓某個人避開犯錯的機會。 p. 215

定義你所發現的問題是否為雜草,主要的考量就是安不安全。如果你能很安全地修正這個問題,那它應該就是要被拔掉的雜草。 p. 216

這定義對超樂觀的開發者而言,所有的瑕疵都是雜草 XD

拔草是一件很簡單的事。如果你知道什麼東西是雜草,把它拔掉就對了。如果你懷疑某個東西是雜草,那就值得花點功夫來確認一下;如果是雜草,拔掉就對了。 p. 219

記得要確認,不然可能會傷了團隊內部的和氣。

守則 16 | 要從結果往回推,別從程式碼往後推

有時候甚至連要解決什麼問題都不太清楚!當你在製作遊戲時,尤其容易發生這種情況,因為在你開始製作遊戲之前,實在很難預測是什麼東西會很有趣。 p. 221

每個間隔都會把東西分成兩邊。你總是站在其中的一班,望向另外的一邊。問題是 —— 你究竟是站在手握許多程式碼的那一邊,還是站在有很多問題的那一班呢? p. 221

你可以想想看,你是不是會根據手頭上的程式碼,來考慮所要面對隊的問題?還是你會透過問題的角度,來考慮你的程式碼? p. 221

守則 17 | 有時候大問題反而好解決

大多是時候,比較具有針對性的解法,往往比通用的解法更容易進行實作。你還是應該盡可能去解決你所能理解的問題。不要輕易嘗試去透過通用的做法來解決問題,除非你有足夠多的例子,可以確定這個問題確實值得用比較通用的方式來解決。 p. 253

我們所有「通用解法就是更簡單的解法」這樣的例子,全都是「在視角上必須做出重大改變」的情況。通用的解法往往代表一種完全不同的問題思考方式,而這種全新的視角,就促成了一個從根本上來看更簡單的解法。 p. 254

守則 18 | 讓程式碼自己講故事

從某種意義上來說,註解說明就是永遠不會執行的程式碼 —— 它最接近被執行的情況,就是有人真的去讀它,而且還把註解說明與實際的程式碼進行了比較。 p. 257

如果函式的某個參數絕不能是 null,請不要用註解說明來描述這件事 —— 改用下斷言的做法就好了。 p. 257

若程式語言的設計本身就能處理,該有多好。Java 快去學學 Swift 啊。

好的註解說明會告訴讀程式碼的人,一些與程式碼相關,但又「不是很明顯的」東西。註解說明若只是概要簡述一些顯而易見的東西,這樣的內容雖然是正確的,卻沒甚麼用處。一個好的註解說明,可以幫助讀程式碼的人理解程式碼,可以解釋程式碼為什麼要這樣寫,可以給出函式的預期使用方式。 p. 259

守則 19 | 以平行方式進行改造

打造一整組平行的時做程式碼,然後在執行階段用一個標記來做為開關進行切換。 p. 279

也就是 feature toggle,但說真的,這一節的範例對 C++ 不熟的人真的會很吃力,已經十幾年沒寫 C++ 了,也是要花點時間才能看懂。

一步一步採取比較小而安全的步驟。在這樣的做法下,如果你在過程中遇到任何障礙,你還是可以快速回到原來的行為方式,這樣一來整個團隊就不會受到影響了。 p. 285

如果你根本無法定義出一個轉接層,在新舊版本之間以動態方式進行切換,這樣就無法套用我在這裡描述的技術做法了。 p. 286

守則 20 | 還是要用數學算一下

其實這只不過是個數學問題而已!如果你去寫自動化程式碼的時間,比你用人工方式重複執行任務的時間還好,那就是值得的。如果不是如此,那就不值得。 p. 288

我們都是因為很喜歡設計程式,才變成一個程式設計者的。我們一定會比較傾向透過程式設計的方式來解決問題 —— 可是,程式設計並不一定是解決所有問題的正確做法。 p. 288

你認為下面哪一種可能性比較大呢 —— 是你對自動化的效益估計過於悲觀,還是你對程式碼所需的時間過於樂觀?身為一個程式設計者,你一定知道這個問題的答案。你絕對比較有可能錯估自己寫程式所要花的時間。 p. 290

因此,我們都會先去確認一些天生就存在的硬性限制,然後再根據一些軟性限制自行創建出一些硬性限制,以簡化我們的設計決策。… (略) ... 大家其實很難理解,那些軟性的限制究竟該如何去進行權衡取捨。映現的限制就比較容易了 —— 它會把設計程序的某些部份變成簡單的數學計算,而且坐起來蠻容易的。 p. 291

數學計算會告訴你,最初的設計是行不同的。在真正寫出所有程式碼之前,先在數學計算上切換設計,顯然會容易許多。 p. 294

重要的是一定要注意,進行數學計算的目的,主要是為了提前發現無效的解法,不過倒不一定能驗證出某個解法是不是有效的。 p. 294

如果自動化之後,就可以讓工作從美洲變成每天做一次,這樣或許就值得去做,雖然省下來的時間並不多。 p. 296

不要怕偶爾花一天時間,去讓大家的生活更愉快 —— 尤其是當數學計算結果差距不大的情況下。 p. 296

守則 21 | 有時你就是得去做一些敲釘子的工作

並不是每個問題都有優雅的解法。就算是最激動人心的程式設計工作,也有單調沉悶的時刻:也就是那些沒人感興趣的工作、很難讓人感到興奮的工作、沒人願意去做的工作之類的。大家很自然就會去做其他比較讓人興奮的事,不斷把那些苦差事往後拖延。 p. 299

不要在跳過苦差事了。那些不討人喜歡的工作,沒人舅舅不會有任何進展。天底下並沒有什麼程式碼精靈大軍,會在你睡覺時幫你完成工作。未完成的工作只會變成一種慢性毒藥,扼殺掉你的專案。 p. 299

毒藥,真的,但我無法透露更多了。

就算是一支紀律嚴明的團隊,要大家投入到苦差事還是很困難。 p. 307

結論:制定出你自己的守則

就我個人而言,我會把所有的「小型」程式設計團隊,定義成一個人就可以徹底了解所有程式碼全部細節的團隊。 p. 309

我們確實有一些程式碼必須「執行」得非常快,不過我們大部分的程式碼,能夠很快速「建立起來」才是比較重要的事。 p. 310

我們所做的改動,通常都是在我們仔細檢查過很久之後,才會出現在玩家的體驗之中。如果稍微容忍一下某些暫時性的 bug,有助於我們更快把遊戲建立起來,我們就會選擇這樣做。 p. 310

如果我們每個禮拜都要發布新版本,那絕會會有另一種截然不同的做法。 p. 310

技術上的討論與理念上的討論經常都會糾纏不清,這也是很難避免的狀況。不過,這絕不是能獲得進展的秘訣。這兩種討論最好還是能分開來,因為這樣你們才比較有可能得到一個比較快樂的結局。 p. 312

如果你們可以在如何寫程式的理念上達成一致,你們這個團隊一定會更有效率,而達到這個目標最快的方式,就是多去討論你們的這些想法。 p. 312


這陣子比較有空可以去天瓏書局晃晃,正好看到這本剛上市不久的書,整體上大多數守則,也是我自己一直在遵循的,是相當不錯的一本總結書。但真的要仔細看每一節的內容,理解每個原則背後的情境與想要改善的問題是什麼。如果只是把每一節的標題拿來使用,很容易就會發現衝突的部分。

分享至
成為作者繼續創作的動力吧!
內容總結
程式設計守則
5
/5
© 2024 vocus All rights reserved.