2018/06/19

程序員的修煉之道 (The Pragmatic Programmer) 讀書心得 - CH2 注重實效的途徑

CH2 注重實效的途徑

程式開發也存在著一些普遍適用的想法和過程
這一章就是在講這些

重複的危害

  • 你開發的系統需要維護
  • 維護意味著要找到需要修改的地方
  • 如果需要修改的地方散落各處會增加維護的難度
  • 重複: 這不是你記不記得住的問題, 而是你什麼時候忘記的問題

重複怎麼發生的?


強加的重複
  • 多重表示的訊息
    • Client-Server 的 Application, 在 Client 端會需要設計不同語言的呼叫端程式
    • 瀏覽器大戰時, 要針對不同的瀏覽器寫相容的javascript
  • 用程式產生器去產生不同語言的程式碼
問題: 如果你是資安單位, 你設計了一個防範CSRF的底層, 但公司用的技術有PHP, ASP.NET, JSP, 需要不同語言的函式庫, 你會怎麼做?

  • 不好的程式碼就代表重覆, 程式碼寫一遍, 注釋再寫一遍
    • 無法從程式碼看出設計意圖, 所以補上大量的注釋, 因此在修改程式碼時, 要一併修改注釋
  • 把程式碼寫的簡單易懂, 容易閱讀
  • 你寫的程式不是給自己看的, 是寫給別人看的
  • 好的程式就像一個好的笑話, 不用解釋就懂

問題: 文件容易過期, 人腦也靠不住, 如何讓領域知識有效率的傳承?

  • 語言特性的問題
  • 重複會增加維護的成本時, 可能就需要去處理它
問題: Config 檔分成多個環境的版本是否是DRY?

無意的重複

  • 注意類別裡可以自動計算的 propertie
  • 例如: 長度、重量、材積 … 等等

無耐性的重複

  • 因為時間壓力, 或是為了方便, copy-past一段code再小部份的修改, 這反而造成了維護時的壓力 (code 看起來有87%像)
  • 記住"預速則不達", 儘量用重構的方式處理
問題: 什麼時間是好的重構時機?

開發者之間的重複

  • 重複開發相同的功能或底層 (台灣 vs 大馬 code base?)
  • 太喜歡自己造輪子
問題: 在敏捷團隊中, 不鼓勵分層負責開發, 要如何管理重覆的問題?
團隊間或是開發者之間主動交流
讓別人容易找到你的東西

正交性

  • 非正交性的設計, 造成相依性過高, 容易改A壞B
  • 編寫正交性的系統, 可以以得到二個主要的好處:
    • 提高生產率
    • 降低風險
Orthogonality

提高生產率

  • 可以局部修改, 開發跟測試的時間降低
  • 程式碼可以重用
  • 減少重疊的功能, 透過組合就能提高生產率

降低風險

  • 有問題的程式碼可以被隔離
  • 改動只限於局部範圍, 影響也是
  • 測試更容易
  • 不會被特定的組件、服務提供商或平台綁住

項目團隊的正交性

  • 團隊裡任務有重疊, 責任就會劃分不清
  • Componet Team VS Feature Team?
  • 團隊裡有不同的功能專家
    • 定義好彼此的溝通介面
  • 人數愈多, 正性性愈差 <== 溝通成本上升
  • 子團隊要不斷的交流

設計

  • 設計好組件時, 想看看改動時會影響多少模塊?
  • 不要依賴你無法控制的事物
    • 把電話號碼當成客戶的Identity ID

工具箱與庫

  • 引入第三方工具時, 注意保持正交性, 明智的選擇技術
  • 面向切面導向程式設計(Aspect-Oriented Programming, AOP)
  • 問題: 如何跟Nuget套件保持正交性?

程式碼

  • 保持解耦
  • 避免用全域數據
  • 避免編寫相似的函數
  • 找機會進行重構

測試

  • 建構單元測試可以測試系統是否保時正交性
  • 修bug的時候也是評估正交性的時機
  • 改A壞B, 難以評估影響範圍也許就是因為系統沒有保持正交性
問題: 遇到難以重現的問題該如何處理?

文檔

  • 你應該可以顯著的改變外觀, 而不是改變內容
  • 建議用Markdown語法

問題: 你參與了一個專案, 當大家在不顧一切地做出改動時, 每一處改動好像都會造成別的東西出錯…
為什麼會這樣? :fire:

可撤消性

  • 現實世界不斷的在變化
  • 當你嚴重依賴某一事實, 就幾乎可以斷定它將變化
  • 實現一種東西, 不會只有一種方式
  • 不要被第三方服務供應商控制
  • 把決策視為寫在沙灘上, 而不是刻在石頭上

靈活的架構

  • 維持架構、部署及服務供應商等領域的靈活性
  • 無論你使用那種機制, 讓它可撤消
  • 如果東西是自動添加的, 讓它可以被自動去除
  • 讓你的代碼學會"搖滾"

薛丁格貓
決策會造成多個平行宇宙, 你的程式碼可以支援多少個未來?

曳光彈

曳光彈 vs 原型制作

  • 曳光彈不是用過即扔 ==> 迭代開發, top-down 開發
  • 原型制作對概念進行實驗 ==> LinqPad, 實驗性的 Console Application
  • 先用原型確認曳光彈要往那個方向發射

領域語言

  • Domain-specific language
  • 可以用來當作捕捉用戶需求的一種方式
  • 進一步讓它變規範, 變成可執行的代碼
  • 感覺是為了甲方乙方確認規格使用, 應該有更好的方式?

估算

  • 確認可行性
  • 解答的情境是什麼?
  • 估算的單位是什麼?
  • 估算的基礎來自經驗
  • 建立系統模型, 找出相關的變因
  • 分解
  • 計算答案
  • 追蹤你的估算能力

估算專案進度

  • 檢查需求
  • 分析風險
  • 設計、實現、集成
  • 向用戶確認
基於被代開發的經驗, 提煉你原來對迭代的次數
把改進的進度表當成迭代的一部份

在被要求進行估算時要說什麼?

  • 延後決策
  • 放慢估算的速度
寫日誌記錄你的估算能力

程序員的修煉之道 (The Pragmatic Programmer) 讀書心得 - CH1 注重實效的哲學

CH1 注重實效的哲學


1. 我的源碼讓貓給吃了


Provide Options, Don’t Make Lame Excuses
提供各種選擇, 不要找蹩腳的藉口
  • 不要害怕暴露弱點, 不害怕承認無知或錯誤
  • 負責, 犯錯時勇於承諾
  • 不要害怕提出要求, 也不要害怕承認你需要幫助
這些藉口你聽過幾個?

2. 軟件的熵


熵就是無序的狀態, 不要放任無序生長
Don’t Live with Broken Windows
不要容忍破窗戶
  • 看到一個問題修一個, 避免惡化
  • 如果團隊的代碼十分漂亮, 你也不會想成為第一個弄髒的人

挑戰
  • 說說看你的團隊裡的破窗何時產生的? 誰的決策? 你的反應是什麼?
  • 分享一下團隊修理破窗的經驗

3. 石頭煮青蛙


Be a Catalyst for Change
做變化的催化劑
你知道是對的, 也知道怎麼做, 那就做下去吧!
請求原諒比獲得許可容易

Remember the Big Picture
記住大願景
  • 要持續不斷的觀察週圍發生的事情, 而不是只有你自己在做的事
  • 看見全貌
  • 專注在目標
  • 設檢核點
  • 每次檢核都要確認有朝著目標前進

挑戰
  • 當你在設法做催化劑時, 想想你在做石頭湯還是青蛙湯? 決策是主觀還是客觀?

4. 足夠好的軟件


  • 能解決客戶問題的足夠好的軟體就可以了, 要知道世界上沒有完美的軟體
  • 讓用戶參與, 使質量成為需求問題
  • 讓用戶先使用, 早期取得回饋, 可以導向更好的解決方案
  • 知道何時止步, 不要過度打磨

5. 你的知識資產


知識資產會過期, 要定期投資
給自己訂目標
  • 定期為你的知識資產投資
  • 多元化、管理風險、低買高賣、重新評估和平衡
  • 每年學一種新語言
  • 每季閱讀一本技術書
  • 也要閱讀非技術書
  • 上課、參與社群、試驗不同的環境、跟上潮流和上網學習

把握學習的機會
  • 把找到答案視為對你個人的挑戰
  • 怎麼知道學習有成果? 開始教別人
  • 抓零碎的時間學習

批判的思考
  • 盡信書不如無書
  • 不要小看商業網路推薦的力量

6. 交流


  • 我們花費很多時間在交流, 所以要把它做好
  • 規劃你想要說的東西, 寫出大綱
  • 了解你的聽眾要的是什麼
  • 選擇對的時機交流
  • 依你的聽眾選擇交流的風格
  • 讓文檔美觀, 檢查拼寫, 先自動再手動
  • 回覆他人, 讓他人有受尊重的感覺

程序員的修煉之道 (The Pragmatic Programmer) 讀書心得 - 序篇

有些書的序我會跳過不看, 但這本書的序我強烈建議一定要看, 它寫了一相當有價值的東西。
本書的英文書名叫:重視實效的程序員(Pragmatic Programmer)

什麼是重視實效? 在現在這個快速變化的世界, 昨天的好架構明天可能就變成反模式, 程式語言及工具也推陳出新, 許多老的工程師會嘆跟不上時代, 或是在這行實在太累了, 永遠都要學習。 

撇開終生學習這個高大上不談, 程式開發還是有些特性是不太會變的, 本書要講的就是這些可以幫助大家成為更好的程式設計師的一些方法。 

什麼是重視實效? 意思是你不該局限于任何特定的技術, 而是應該擁有足夠廣博的背景及經驗基礎, 以讓你能在特定情況下選擇好的解決方案。

我喜歡這種書是因為你可以在任何時候回來翻它, 翻完後可以得到更多的靈感。

程式員的修煉之道 - 序



編程是一種技藝, 你每天都在創造小小的奇蹟。


編程是艱難的工作, 不存在最佳解決方案這種東西
能夠存在的只是在某些特定情形下更為適宜的系統

注重實效
  • 意思是你不該局限于任何特定的技術, 而是應該擁有足夠廣博的背景及經驗基礎, 以讓你能在特定情況下選擇好的解決方案。
  • 注重實效的程序員不僅要完成工作, 而且要完成得漂亮。

注重實效的程序員有以下特徵
  • 早期的採納者/快速的改編者
  • 好奇
  • 批判的思考者
  • 有現實感
  • 多才多藝

但, 最基本的特徵是
  • Care About Your Craft 關心你的技藝
  • Think! About Your Work 思考! 你的工作

挑戰
  • 在你做某件事情的時候思考你在做什麼。
  • 對你每一天、每一次開發上所做的每一項決策做出批判評估。

你在大型團隊中, 仍然可以是注重實效的個體
是木匠、石匠、雕刻工和玻璃工之類的手藝人
超越了純粹機械方面的一個整體
軟體工藝的支柱: Care、Learn、Practice、Share

它是一個持續的過程
改善: 持續地做出許多的小改進
豐田形學: Improvement Kata

台灣著名的鋼琴家「Pianoboy」高至豪
  • 你有什麼夢想?
  • 如果你願意為了它,努力數十年而不停止
  • 如果你願意努力推銷自己的夢想10年,既使遇到無數的否定和嘲諷還是願意前進
  • 如果你願意堅信你的判斷,既使放棄穩定的薪水和工作,既使失敗,也願意
  • 我相信大部分人,絕對會比我更成功。

軟體工程的重要的指標