《人月神話》簡易心得
這本真的是很有收穫的書籍,對於在軟體產業工作(尤其是by專案),看完有著很大的共鳴跟反思。(還沒進產業時曾看過一遍,實際工作後再看一遍又有更深的體會。)
重點是這是三十年前寫的書,而隨著技術與工具的進步,軟體專案發展到現在仍然有書中所說的種種困境與難題,看完會覺得作者真的對軟體專案看得很透徹。
簡短心得就把每一章濃縮成我覺得最重要的「一兩句話」,避免太發散。
但書裡面的內容絕對不只、也無法用一句話精準的概括,只是這樣比較方便記憶而已。
第一章 焦油坑
大型軟體專案就像焦油坑,再大再厲害的高手,踏進去了,欲掙扎就只會陷得愈深,最終慘遭滅頂。
開發系統要注意的眉眉角角非常多,不是厲害的高手就能一路順暢,每次面臨的情境也都不同。
第二章 人月神話
人月是個可以用來計算「成本」的指標,但拿來衡量「產出」卻會造成很大的偏誤。
高手跟新手的生產力跟品質是數量級的差異,而且難以量化。這也是為什麼專案管理如果用人月來計算時程進度,幾乎都無法照著預期走。且專案經常有著潛在假設「一切都會順利按照計劃進行」,造成根本上的預期錯誤。
coding所佔的時間是整個專案最少的時間
1/3 規劃
1/6 coding
1/4 早期測試
1/4 系統測試&完成組件
第三章 外科手術團隊
團隊成員越多反而越不利,短小精悍的團隊才是軟體專案的最佳team。
成員多,代表「溝通」勢必更多,最後這些溝通成本會超過增加人手所帶來的效益。只需要在必需的角色上各有一人,效率才是最高的。外科手術團隊的重點在於團隊目標是一致的,不允許決策上的多頭馬車。
第四章 專制、民主與系統設計
「Form is liberating.」(形式就是解放)
系統設計常常是在有限的資源(時間、技術、預算等),這些未必是限制,恰恰是因為有這些限制(約束專案的範圍),我們的創意才能夠發揮。
大型軟體專案就像焦油坑,再大再厲害的高手,踏進去了,欲掙扎就只會陷得愈深,最終慘遭滅頂。
開發系統要注意的眉眉角角非常多,不是厲害的高手就能一路順暢,每次面臨的情境也都不同。
第二章 人月神話
人月是個可以用來計算「成本」的指標,但拿來衡量「產出」卻會造成很大的偏誤。
高手跟新手的生產力跟品質是數量級的差異,而且難以量化。這也是為什麼專案管理如果用人月來計算時程進度,幾乎都無法照著預期走。且專案經常有著潛在假設「一切都會順利按照計劃進行」,造成根本上的預期錯誤。
coding所佔的時間是整個專案最少的時間
1/3 規劃
1/6 coding
1/4 早期測試
1/4 系統測試&完成組件
第三章 外科手術團隊
團隊成員越多反而越不利,短小精悍的團隊才是軟體專案的最佳team。
成員多,代表「溝通」勢必更多,最後這些溝通成本會超過增加人手所帶來的效益。只需要在必需的角色上各有一人,效率才是最高的。外科手術團隊的重點在於團隊目標是一致的,不允許決策上的多頭馬車。
第四章 專制、民主與系統設計
「Form is liberating.」(形式就是解放)
系統設計常常是在有限的資源(時間、技術、預算等),這些未必是限制,恰恰是因為有這些限制(約束專案的範圍),我們的創意才能夠發揮。
試想:如果是一個沒有主題的競賽或作品,到最後就會完全發散掉了。
系統的主體性大於個人的創意
必須維持主體性,如果每個人都依照自己的想法去設計,最後系統就會變成四不像。A功能有A風格,B功能有B風格,最後讓系統一點都不好用。套用到coding也是,為什麼需要coding guildeline、code review,維持整個code一致性,會比追求最新的技術、寫法的好處更多。
第五章 第二系統效應
「根據經驗法則的歸納,設計師所操刀的第二個系統通常是over design的」
(怎麼馬上讓我想到windows OS歷史,隔代魔咒..一代成功接著下面那一代就是慘)
設計的工作「自律」很重要,通常第二次就會想把前一次想到的點子都加進去嘗試,因為第一次做會小心翼翼,不敢加太多不熟的東西。第二次就想把熟悉的東西發揮到最大(結果是過時的東西),或是加進當時想到卻沒做的“創意”,最後就變成怪物的系統。
第六章 意念的傳達
避免誤解(表達者跟接收者的認知不同)
這章節的舉例不太懂,有些內容感覺已經被現在的技術解決了。不過我想作者的重點是提出很多方式來降低誤解的發生,我認為重要的:
1.開會(確定方向、每個人都是)
2.系統文件(詳細的文件避免實作上的誤解)
3.通聯紀錄(留存各種瑣碎的資訊)
4.測試(確保產出跟當初的概念是一致的)
會議,讓參與者盡可能的加入,每個人都可以提案跟表達,因為每個人都跟系統有利害關係,在會議能避免本位主義跟適當的妥協。每週的會議,確定大家的方向仍然一致,也可以及時討論修正。
第七章 巴別塔為什麼失敗?
當具備了所有資源,大型專案卻容易因「溝通」跟「組織」而失敗。
組織通常是樹狀的(單一指揮鏈),但溝通應該要偏向網狀。在組織結構上,管理面跟技術面最好是兩個分開的leader(小型的話可能可以給同一個人負責,如果那個人同時有這兩種特質)。技術層面的決策最大的權力在首席工程師上,管理leader要尊重,不應該干擾,這樣才符合外科手術團隊的概念,避免設計系統上不知道要聽誰的。
第八章 預估
不要拿coding時間來預估整個專案的時間
就像拿百米賽跑成績來預測馬拉松的時間一樣,會得到一個跟實際天壤之別的預測。
coding人員大該一天只有一半的時間是好好寫程式,其他時間可能有各種雜務、行政、測試等干擾。
第九章 地盡其利,物盡其用
空間與時間的取捨,是要依照使用者情境而定
軟工領域都知道時間換空間/空間換時間的trade-off,尤其是愈底層的程式,一點點的偏差都會造成很大的影響。像我們做應用系統的,也是很多地方要取捨,最好的準則是以系統整體性,使用者導向為主,不要有各功能(或是開發團隊)的本位主義,結果變成「各個功能獨立來看都是最佳,結果組合起來卻是最慘」。
第十章 文件假說
正式文件是有其必要性的,即便是個無趣的工作也要做。
專案的規劃的文件,經常遇到一個非常實際的情境,「我們常常知道第一版文件只是暫時性的,未來一定會修改,到時候又要改文件很麻煩,所以造成一開始就懶得做,總想說最後再來做文件,然而最後就是沒有文件。」
如果沒有正式的規劃文件,就很難具體的討論跟實作。我們在做實體物品的時候,都會有個設計圖吧,很少會直接把原料拿來就開始做;然後做系統會有個誤區,就是認為可以很快利用程式碼,把概念直接轉換成系統。因為系統的“原料”就是我們的想法,僅此而已,沒有什麼看得見摸得著的實體,但這反而更需要有個具體的文件,來描述出這個系統到底應該長怎樣,利於討論跟確認想法是否有漏洞。
第十一章 失敗為成功之母
通常做出來的第一個版本的系統都是不能用的
「唯一不變的就是變」
為什麼會這麼說?接續前一章的評論,因為系統的原料就是我們的想法,即便考慮的再周到,實作後總會發現有哪些地方是當初沒考慮到的,或可以再更好。
而且大型專案時程長,一定也會遇到技術上的更新,像是新框架新語言的出現。那要怎麼面對這種情況?答案是讓系統「利於改變」,也就是後來的OO概念、模組化這些東西,讓系統的彈性提高,模組間降低耦合性,隨時可以更新某個小區塊。
上面是對系統面而言,對組織面也是有對應的概念,像是scrum這種敏捷開發的方法論,要隨時準備好面對環境在改變的事實。
第十二章 神兵利器
善用現有的或更新的工具輔助
作者當時的情境是沒有高階語言、批次執行的時代,所以本章介紹的很多技術已經被克服,甚至提出更好的工具。
簡言之,本章的重點在於做專案一定要善用現有的支援工具,舉例來說,最基本的版本控制(Git)、自動化部署測試CI/CD(Jenkins)、選用方便的高階語言、開源/第三方的套件,每個領域都有各自的工具可以用,善用工具可以提高專案的效率。
不一定每一樣都要精通,專案團隊最好有一位這種工具專家(但我覺得應該是每種項目有專家,然後共享給各個專案,比較適合)。
系統的主體性大於個人的創意
必須維持主體性,如果每個人都依照自己的想法去設計,最後系統就會變成四不像。A功能有A風格,B功能有B風格,最後讓系統一點都不好用。套用到coding也是,為什麼需要coding guildeline、code review,維持整個code一致性,會比追求最新的技術、寫法的好處更多。
第五章 第二系統效應
「根據經驗法則的歸納,設計師所操刀的第二個系統通常是over design的」
(怎麼馬上讓我想到windows OS歷史,隔代魔咒..一代成功接著下面那一代就是慘)
設計的工作「自律」很重要,通常第二次就會想把前一次想到的點子都加進去嘗試,因為第一次做會小心翼翼,不敢加太多不熟的東西。第二次就想把熟悉的東西發揮到最大(結果是過時的東西),或是加進當時想到卻沒做的“創意”,最後就變成怪物的系統。
第六章 意念的傳達
避免誤解(表達者跟接收者的認知不同)
這章節的舉例不太懂,有些內容感覺已經被現在的技術解決了。不過我想作者的重點是提出很多方式來降低誤解的發生,我認為重要的:
1.開會(確定方向、每個人都是)
2.系統文件(詳細的文件避免實作上的誤解)
3.通聯紀錄(留存各種瑣碎的資訊)
4.測試(確保產出跟當初的概念是一致的)
會議,讓參與者盡可能的加入,每個人都可以提案跟表達,因為每個人都跟系統有利害關係,在會議能避免本位主義跟適當的妥協。每週的會議,確定大家的方向仍然一致,也可以及時討論修正。
第七章 巴別塔為什麼失敗?
當具備了所有資源,大型專案卻容易因「溝通」跟「組織」而失敗。
組織通常是樹狀的(單一指揮鏈),但溝通應該要偏向網狀。在組織結構上,管理面跟技術面最好是兩個分開的leader(小型的話可能可以給同一個人負責,如果那個人同時有這兩種特質)。技術層面的決策最大的權力在首席工程師上,管理leader要尊重,不應該干擾,這樣才符合外科手術團隊的概念,避免設計系統上不知道要聽誰的。
第八章 預估
不要拿coding時間來預估整個專案的時間
就像拿百米賽跑成績來預測馬拉松的時間一樣,會得到一個跟實際天壤之別的預測。
coding人員大該一天只有一半的時間是好好寫程式,其他時間可能有各種雜務、行政、測試等干擾。
第九章 地盡其利,物盡其用
空間與時間的取捨,是要依照使用者情境而定
軟工領域都知道時間換空間/空間換時間的trade-off,尤其是愈底層的程式,一點點的偏差都會造成很大的影響。像我們做應用系統的,也是很多地方要取捨,最好的準則是以系統整體性,使用者導向為主,不要有各功能(或是開發團隊)的本位主義,結果變成「各個功能獨立來看都是最佳,結果組合起來卻是最慘」。
第十章 文件假說
正式文件是有其必要性的,即便是個無趣的工作也要做。
專案的規劃的文件,經常遇到一個非常實際的情境,「我們常常知道第一版文件只是暫時性的,未來一定會修改,到時候又要改文件很麻煩,所以造成一開始就懶得做,總想說最後再來做文件,然而最後就是沒有文件。」
如果沒有正式的規劃文件,就很難具體的討論跟實作。我們在做實體物品的時候,都會有個設計圖吧,很少會直接把原料拿來就開始做;然後做系統會有個誤區,就是認為可以很快利用程式碼,把概念直接轉換成系統。因為系統的“原料”就是我們的想法,僅此而已,沒有什麼看得見摸得著的實體,但這反而更需要有個具體的文件,來描述出這個系統到底應該長怎樣,利於討論跟確認想法是否有漏洞。
第十一章 失敗為成功之母
通常做出來的第一個版本的系統都是不能用的
「唯一不變的就是變」
為什麼會這麼說?接續前一章的評論,因為系統的原料就是我們的想法,即便考慮的再周到,實作後總會發現有哪些地方是當初沒考慮到的,或可以再更好。
而且大型專案時程長,一定也會遇到技術上的更新,像是新框架新語言的出現。那要怎麼面對這種情況?答案是讓系統「利於改變」,也就是後來的OO概念、模組化這些東西,讓系統的彈性提高,模組間降低耦合性,隨時可以更新某個小區塊。
上面是對系統面而言,對組織面也是有對應的概念,像是scrum這種敏捷開發的方法論,要隨時準備好面對環境在改變的事實。
第十二章 神兵利器
善用現有的或更新的工具輔助
作者當時的情境是沒有高階語言、批次執行的時代,所以本章介紹的很多技術已經被克服,甚至提出更好的工具。
簡言之,本章的重點在於做專案一定要善用現有的支援工具,舉例來說,最基本的版本控制(Git)、自動化部署測試CI/CD(Jenkins)、選用方便的高階語言、開源/第三方的套件,每個領域都有各自的工具可以用,善用工具可以提高專案的效率。
不一定每一樣都要精通,專案團隊最好有一位這種工具專家(但我覺得應該是每種項目有專家,然後共享給各個專案,比較適合)。
第十三章 化整為零
系統採用top-down設計比較好,且需要充分的測試案例
top-down設計可以從全體性建立基本的架構,好的架構下再慢慢去設計各個模組,最後交給實作。如果沒有好的架構,就像在不穩的地基上蓋房子,再怎麼蓋都是爛。
第二個重點是需要充分測試,像現在就有測試驅動開發(Test-driven development, TDD),但這部分我沒深入研究,只知道其主要概念是先寫測試,再開發功能。
第十四章
millstone必須是一個明確的東西,只有「完成」與「沒完成」,沒有已經完成 90%這種答案。
里程碑就是一個檢核點,沒有達成代表出大事,完成90%跟完成70%都代表著delay,如果里程碑不是全力以赴必定要完成的目標,訂定就沒有意義。
但里程碑也不是不能調整,只是不能頻繁,而且調整的層級需要分,最高階管理者訂個區間,再交由一線的主管訂出合理可達成的具體時間,因為一線主管最清楚具體的內容,這樣才會精準又可執行。
這樣有另一個好處,就是給一線主管有發揮的空間,讓他去做決定&負起delay責任,可以激勵出更多正面的動力。
留言
張貼留言