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

估算

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

估算專案進度

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

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

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

沒有留言: