2009年1月27日

[讀書筆記] The Pragmatic Programmer (Chapter 8 END)

Chapter 8 - Pragmatic Projects


Section 41: Pragmatic Teams

( 本節以團隊的角度重新走了一遍先前的章節們。)
團隊間的熱情可以互相勉勵,質量由全員貢獻。不要保留破窗、不要被呆呆地煮熟;對內交流熱絡,對外口徑一致。DRY、orthogonality 是值得花費心思分配的事。給予成員們能夠以自己的方式閃耀的空間,但也要知道何時該停下來。


Section 42: Ubiquitous Automation

Don't use manual procedures. 人類的可重覆性並不像機器那麼好,而且手動完成機器就可以完美處理的東西 並不是一件值得誇耀的事。保留自己的時間精力來做更重要、更困難、更有趣的事吧。


Section 43: Ruthless Testing

Test early. Test often. Test automatically. Coding ain't done 'til all the tests run.

測試的範疇:Unit testing → Integration testing → Validation and verification ( 軟體有做它應該完成的事嗎?) → Resource exhaustion / errors ( 如何應變?能否讓軟體復原?) → Performance testing → Usability testing ( 真實環境下實際使用的狀況、手感 )、Regression testing ( code 更新後是否還能通過先前的 test cases?)

Test your testing. Find bugs once.

老樣子:Test your software, or your users will.


Section 44: It's All Writing

好記性不如爛筆頭。 --中國諺語

文檔也是開發中重要的環節。將 code 和 documentation 當成同一 model 的兩種 view。以適當的 comment 寫在 source code 中是一種方法,可以使用自動化工具來提取它。


Section 45: Great Expectations

滿足了客戶的期望,才算是成功。並且,如果想讓客戶高興的話,還得再多做一點點......


Section 46: Pride and Prejudice

防止匿名所造成的品質低落,抑或宣示值得自豪的作品,sign your work.



另有 Quick Reference Guide,是書中觀點精華,值得收藏。



總算讀完了......

整體感覺,就一本 1999 年出版的書來說,所闡述的多樣內容依然歷久彌新。可以想見為何 TPP 會成為這行的經典之一。

書中讓我印象最深刻的一句話,是 Section 38 出現的:

Software development is still not a science.

很奇特的觀點,眼神為之一亮 (。◕‿◕。)

以往我一直覺得程式設計主要鍛練邏輯思考:資料結構、演算法、循序 / 選擇 / 重覆...... 讓人整個條理化起來。加之多年來興起的大批方法論,似乎都愈加將它拉入理科範疇。

而從該句的觀點來看,確實也有另一番道理:畫家在畫布上揮灑,程設師在鍵盤上敲打,同樣都是為了創造、轉化腦海中所想表達的而努力 ( 只是女孩子的傾心程度會不一樣 )。

把自己當成一個隨興不拘的藝術家,貌似也頗不錯 (>ω<)♪♪


我所讀過的書,圈出了我所知道的宇宙邊界。

仔細回想,其實我從中學開始就不曾再大量閱讀了......。接觸電腦之後,所有注意力都從歡樂雜書叢中抽離。到現在還延用十年前所得的知識,以及延途隨手採摘的小花朵,真是相當汗顏啊 (||。3。)

網路確實是很偉大,不過也有比不上實體書的地方。
該是時候重拾書本了......


在這綿延伸展至無窮遠方的道路上,我又多完成了一小段。可喜可賀。

2009年1月26日

[讀書筆記] The Pragmatic Programmer (Chapter 7)

Chapter 7 - Before the Project


Section 36: The Requirements Pit

Perfection is achieved, not when there is nothing left to add, but when there is nothing left to take away.
--Antoine de St. Exupery, Wind, Sand, and Stars, 1939

需求不是架構 / 設計 / UI。Requirements are need,是對某件需要完成的事的陳敘。

Don't gather requirements—dig for them. 瞭解需求背後的原因而不僅僅是方式。

Work with a user to think like a user. 切身瞭解客戶需求,共創和諧社會。對專案建立詞彙表,確保所想的和客戶所講的是同一樣東西。

使用簡單準確的敘述來描述需求,避免規定過度。Abstractions live longer than details.


Section 37: Solving Impossible Puzzles

難題給出約束,並限制自由度,局限、誤導思考方向。Don't think outside the box—find the box. 確定了真正的約束之後,才能証明某些解法確實無用。否則就只是畫地自限,親手扼殺了正確解法。

有些時候,對需求的重新詮釋能讓整個問題蒸發--它並沒有真的那麼難。


Section 38: Not Until You're Ready

He who hesitates is sometimes saved.
--James Thurber, The Glass in the Field

相信自己累積的經驗與智慧。當感到疑慮時,用 prototype 來驗證它;結果或許可為團隊節省可觀的時間與精力。Start when you're ready.


Section 39: The Specification Trap

Some things are better done than described.


Section 40: Circles and Arrows

Don't be a slave to formal methods. 要記得誰才是主人,從中提煉出更寬廣的世界邊界。

2009年1月25日

[讀書筆記] The Pragmatic Programmer (Chapter 6)

除夕夜,讓 TPP 陪我過年...... QQ

Chapter 6 - While You Are Coding

Coding 不是機械性的工作;在這過程中必須對決策進行仔細的思考和判斷。


Section 31: Programming by Coincidence

深思熟慮地寫 code,別依賴巧合。瞭解自己在做什麼,照計劃行事,並只依靠可靠的事物。


Section 32: Algorithm Speed

Big-Oh notation: worst-case time.
O(n2): on the order of n2.

Estimate the order of your algorithms. Test your estimates.

特別注意當輸入集很小的時候,某些演算法的開銷可能會比其它簡單演算法的還大。


Section 33: Refactoring

Change and decay in all around I see...
--H. F. Lyte, "Abide With Me"

以園藝來比擬軟體開發。重寫 + 重做 + 重新架構 = 重構。重構就是重新設計。

何時重構?違反 DRY / 非正交設計 / 過時知識 / 性能低落。

它得花費額外的時間來完成,不過早期切除腫瘤總是比較好的。Refactor early, refactor often.


Section 34: Code That's Easy to Test

Design to test. 讓 testability 成為軟體的一環。

Unit testing: testing against contract. 保留單元測試並時常跑它。有些現成的框架可以協助完成。

Test your software, or your users will.


Section 35: Evil Wizards

Don't use wizard code you don't understand. 否則就是在靠巧合編程。確保自己完全瞭解了才用。

2009年1月24日

[讀書筆記] The Pragmatic Programmer (Chapter 5)

Chapter 5 - Bend, or Break

為了適應瞬息萬變的步伐,盡力讓 code flexible & adaptable 是必要的。


Section 26: Decoupling and the Law of Demeter

去除不必要的依賴關係,將模組間的耦合降至最小。

The Law of Demeter for functions: object 的任何 method 中都只調用這些 method:obj 自身的、parameter obj 的、持有 / 創建的 obj 的。
代價是可能會需要很多的包裝 來將東西承包出去,因而降低性能。箇中取捨,自行評估吧......


Section 27: Metaprogramming

Configure, don't integrate. 讓演算法、容器、資料庫、GUI style 等都可以自由選擇。

Put abstractions in code, details in metadata. ( metadata 如 Windows 中的 .ini 檔。) 這樣一來便可專注於強健的抽象設計、推遲細節處理。讓程式得以在運行中途改變配置,也是一大優點。

要嘛適應,要嘛 as dead as a Dodo. 演化就是這麼一回事。


Section 28: Temporal Coupling

Analyze workflow to improve concurrency. 降低時序依賴,能減少時間耦合。


Section 29: It's Just a View

GUI 中的 MVC ( Model-View-Controller ) 概念:Model 儲存資料本體 / View 負責顯示 / Controller 控制 view 的呈現 ( 像是放大、縮小等操作 )。如此一來可以解除耦合,像是 Qt 的 Model/View programming 就有呈現這樣的概念。

將 MVC 推廣到 GUI 之外:Model 是目標 obj 的抽象數據模型 / View 解釋 model / Controller 控制 view 並可向 model 提供新數據。一種有用的技術是 model-viewer network。


Section 30: Blackboards

共用的黑板讓大家能匿名、非同步地交換訊息,並協調 workflow。

2009年1月21日

[讀書筆記] The Pragmatic Programmer (Chapter 4)

Chapter 4 - Pragmatic Paranoia

You Can't Write Perfect Software

Pragmatic Programmer 不光是不信任別人寫的 code,他們也不信任自己所寫的。所以他們針對自己的錯誤進行防衛性編程。


Section 21: Design by Contract

與人打交道很困難,所以有了合約這種東西,規範雙方的權利和責任。同樣地,與程式打交道也可以用合約 ( DBC ) 以保證其正確性 ( 做的事不多也不少 )。這包含了 precondition ( 調用 routine 時必須滿足的條件 )、postcondition ( routine 保證會做的事,以及完成後對外圍狀態造成的影響 )、class invariant ( class 會確保由調用者的角度來看,某條件總是為真 )。

於是,routine 與 caller 間的合約就是:所有 precondition 成立時,routine 保證所有 postcondition 和 class invariant 為真。


Section 22: Dead Programs Tell No Lies

Crash early. Crash, don't trash. 程式崩掉比起暗地裡搞爆破好的多。


Section 23: Assertive Programming

用 assertion 確保不該發生的事情絕對不會發生。但是它不應該用來:包起必須執行的述句、取代錯誤處理、產生副作用。


Section 24: When to Use Exceptions

Use exceptions for exceptional problems. Exception 應該保留來處理意外事件,否則可能會影響可讀性、可維護性,破壞封裝、增加耦合。


Section 25: How to Balance Resources

Finish what you start. 用像 XHTML 這樣的嵌套次序釋放資源。負責分配資源的東西,也該負責釋放。本節有給出 C++ 和 Java 處理 exception 時釋放資源的範例。

2009年1月17日

[讀書筆記] The Pragmatic Programmer (Chapter 3)

馬不停蹄,第三章的讀書筆記。


Chapter 3 - The Basic Tools

保持工具的鋒利與契身。工具是雙手的延伸,可以放大你的才幹。


Section 14: The Power of Plain Text

Plain text 是 self-describing 的格式。用它來保存資料。


Section 15: Shell Games

GUI 的優點 WYSIWYG / 缺點 WYSIAYG。The shell is your friend.


Section 16: Power Editing

Use a single editor well.


Section 17: Source Code Control

Always use source code control.

它也同樣適用於工作以外的東西 ( 例如作業系統的配置文件 )。


Section 18: Debugging

開頭引用句就很震撼呢......

It is a painful thing
To look at your own trouble and know
That you yourself and no one else has made it
--Sophocles, Ajax

嗯。程式不會照自己所想的跑,只會照所寫的跑。所有程設師共同、永遠的痛苦......

Bug 已經發生,就別訝異地說「那不可能」。面對它吧。

第一步:Don't panic. 確保程式碼在 compiler 高警告級別下也能正常編譯成功,並搜集 bug 發生時的確實情境,讓它重現。

別歸咎於 OS、compiler。試著描述問題的來龍去脈,可能就會浮現出新觀點。根源或許是在稍遠的地方,而非眼前立即所見。確保以後的測試足夠完整,並清除其它有可能受同一個 bug 影響的地方。


Section 19: Text Manipulation

awk、sed、Tcl、Python、Perl 等都是不錯的 text manipulation language,可以用來讓事情自動化。


Section 20: Code Generators

Write code that writes code.

2009年1月12日

[讀書筆記] The Pragmatic Programmer (Chapter 2)

第二章的讀書筆記。

Chapter 2 - A Pragmatic Approach


Section 7: The Evils of Duplication

Maintenance 是件持續伴隨著開發過程的例行事務。想讓開發、維護、理解都更容易的話,秉持 DRY 原則:Don't Repeat Yourself. 並且 Make it easy to reuse.


Section 8: Orthogonality

( 本節開頭給的關於直昇機操控相依性的例子,實在激生動...... )

正交系統中,某個區域的改變不會影響其它地方。這與 DRY 習習相關。設計 self-contained 的組件,以讓事物間不會相互依賴、影響。正交系統可以增加生產力 ( local fix、reuse ) 並降低風險 ( 模組化了 )。

如何讓 code 保持正交性?建構 decoupled 組件 + 避免 global data + 避免寫出相似的函式 ( DRY )。


Section 9: Reversibility

你很難在一開始就做出最正確的決策,且決策很可能一而再再而三地更改。保持 code 的 modularity + flexibility + portability,並致力讓東西在該滾蛋時能輕易地滾蛋。


Section 10. Tracer Bullets

如何在黑暗的戰場上 以正確的方向和仰角 確實地擊中目標?可以把一堆環境因素丟進電腦求解,或是試射曳光彈並視著彈點修改下次射擊。曳光彈與實彈共享現實的狀況,比起模擬求解更加貼近現實。

Prototyping 是用過即丟的 code,而曳光彈最終將成為整體系統骨架中簡約而完整的一部份。


Section 11: Prototypes and Post-it Notes

Prototype 是目標項目的概略模型,可用來測試特定的 aspect,及早找出潛在問題。製作 prototype 是為得從中得到經驗,以讓之後架構實際項目時能有更佳的基礎。


Section 12: Domain Languages

The limits of language are the limits of one's world. --Ludwig Von Wittgenstein

建立並使用與當前項目相關的小型語言。


Section 13: Estimating

Estimate to avoid surprises.

步驟:瞭解問題 → 建立模型 → 拆分組件 → 代入參數 → 運算求解。給出的估量單位會影響別人對此的精準感。

2009年1月10日

[讀書筆記] The Pragmatic Programmer (Chapter 1)

The Pragmatic ProgrammerCode Complete 2,並列 programming 界呼聲最高的兩本書。
( 至於中譯版,前者只有簡體的「程序员修炼之道」,後者有繁體的「軟體建構之道」。)

評價之高當然得來有自。有幸兩本都到手了...... 努力生時間出來讀 =.=

本篇為 TPP 第一章的閱讀筆記。


Preface

  • pragmatic 這字源於拉丁語的「skilled in business」,再溯源就是希臘語的「to do」。
  • 謹記 programming 是一項工藝;別侷限於特定的技術,而應擁有廣博的知識背景與實際經驗,以適應各種變化,漂亮地完成工作。
  • Pragmatic Programmer 的特徵:多才多藝 + 基於經驗累積起來的自信,能快速地理解新事物 + 有著打破砂鍋問到底的精神 + 不會人云亦云,能做批判性思考 + 能設法洞悉問題的內在本質。
  • 最重要的是,關心自己的技藝,且不間斷地進行思考。
  • 每天持續提煉,最終將能得到豐碩的成果。

Chapter 1 - A Pragmatic Philosophy


Section 1: The Cat Ate My Source Code

負起責任,承認不足之處。給出選項,別給愚蠢理由。


Section 2: Software Entropy

由於破窗效應,在事情惡化、擴散之前,將其修補好。沒人在乎,大家都不在乎了。


Section 3: Stone Soup and Boiled Frogs

石頭湯這玩意兒,我小時候就從床邊故事錄音帶聽過了...... 不過一直覺得只是個歡樂的故事,沒放在心上。現在才猛然發現是個寓言 (||。3。)

帶頭煮石頭湯,帶動所有人。扮演催化劑的角色。

為什麼別人強我這麼多?因為別人每天多進步一點點。
為什麼專案進度 delay 這麼多?因為每天 delay 一點點。
為什麼軟體可以爛成這樣?因為每次爛一點點。

Remember the big picture. 別被溫水煮熟了。


Section 4: Good-Enough Software

與客戶討論軟體何時已經夠好。
「足夠好」的軟體,足夠了。因為在這不完美的世界中,不會有完美的軟體。
知道何時該停下來;不要為了過度的修飾,而失去宏觀的焦點。


Section 5: Your Knowledge Portfolio

An investment in knowledge always pays the best interest. --Benjamin Franklin

遺憾的是,IT 產業日行千里,大量知識都是 expiring asset,淘汰得很快。有幾項管理方法可以稍微改善:保持定期投資習慣 + 多元化 + 風險管理 + 低買高賣 + 重新評估、平衡。
另外也要保持 pragmatic programmer 批判性思考的習慣,確保自己的知識資產是準確的。

總之最重要的就是持續 update & 拓展思維吧......。走上了隨波逐流的這一行,這也是沒辦法的事。生也有涯,而學也無涯。


Section 6: Communicate!

與人交流,無庸置疑是相當重要的一件事。如何做呢?清楚地知道自己想表達什麼 + 瞭解並鼓舞聽眾、與之互動 + 分清輕重緩急並選擇時機 + 美化修飾 + 傾聽。有效的交流能增加自己的影響力。