Robert Martin:agile Software Development——principles, Patterns And Practices@2013

以下是從提供資料中提取並解釋的主要論點:

主要論點: 敏捷軟體開發的核心在於擁抱變化並持續交付有價值的軟體,這仰賴於一組強調個體與互動、可用軟體、客戶合作和回應變化的價值觀與原則。敏捷設計是實現這一目標的關鍵,它不是一次性的前期活動,而是一個持續的過程,專注於通過測試和重構等實踐來保持軟體結構的簡單、乾淨和靈活,並策略性地運用設計原則(如 SOLID 原則)和設計模式來應對設計中的「腐敗」(Design Smells)和管理依賴關係,以構建能夠在不斷變化的需求面前保持穩定和可修改的系統。

詳盡解釋:

  1. 敏捷軟體開發的基礎與價值觀:

    • 提供資料強調,敏捷軟體開發是透過實踐和協助他人實踐,來發掘更好的軟體開發方式。其核心價值觀是「個人與互動重於流程與工具」、「可用的軟體重於詳盡的檔案」、「客戶合作重於合約協商」、「回應變化重於遵循計畫」。這並非否定右側項目的價值,而是強調左側項目在達成目標上更為重要。
    • 強調人是成功的首要因素,一個優秀的流程無法拯救缺乏強大成員的專案,而糟糕的流程甚至會讓最強的成員無效。協作和互動比單純的程式設計才能更重要。
    • 強調可用的軟體是主要的進度衡量標準,而非文件或階段完成度。
    • 強調與客戶的持續和頻繁互動對於成功專案至關重要,合約應規範合作方式而非固定範圍和成本。
    • 強調計畫應靈活並準備好適應業務和技術變化,詳細計畫應僅針對近期工作,遠期計畫應模糊化。
  2. 敏捷開發的核心原則與實踐對設計的影響:

    • 提供資料詳細闡述了敏捷聯盟的十二項原則。這些原則指導著敏捷開發的實踐,並深刻影響著軟體設計。例如:
      • 「最高優先順序是透過早期和持續交付有價值軟體來滿足客戶」:這要求軟體結構允許頻繁的建構和交付。
      • 「歡迎在開發後期改變需求」:這要求軟體設計必須具有高度的適應性和靈活性,以最小化變更帶來的影響。
      • 「頻繁交付可用的軟體」:強調交付的是可執行、可用的軟體,而非文件或計畫。
      • 「業務人員和開發者在整個專案中必須每天一起工作」:強調密切的溝通和持續引導專案。
      • 「持續關注技術卓越和良好設計可增強敏捷性」:這是敏捷設計的核心宣言,強調高品質是高速度的關鍵,混亂的程式碼會阻礙敏捷性。
      • 「簡潔—最大化未完成工作的藝術—至關重要」:鼓勵採取最簡單的、符合目標的路徑,避免過度設計和對未來問題的過度預測。
      • 「最好的架構、需求和設計出自於自組織的團隊」:強調團隊應共同擁有設計並有影響力。
      • 「團隊定期反思如何提高效能,然後相應調整其行為」:強調持續改進流程和設計。
    • 書中特別提到測試(Test-Driven Development, TDD 和 Acceptance Testing)和重構(Refactoring)是實現敏捷設計的關鍵實踐。
      • TDD (測試驅動開發):強調先寫一個會失敗的單元測試,再寫剛好讓它通過的程式碼。這不僅驗證功能,更是設計和文件活動。先寫測試迫使開發者從使用者的角度思考,設計出易於呼叫和測試的程式碼,進而促進程式碼的解耦。自動化的驗收測試也對高層次架構設計產生壓力,迫使系統具有高度的可測試性和解耦性。
      • 重構:定義為「在不改變程式碼外部行為的前提下改善其內部結構的過程」。強調這是一個持續的過程,而不是在專案後期進行的清理工作。透過頻繁的微小轉變並在每次改變後運行測試,可以持續保持程式碼的乾淨、簡單和表達性,防止設計的「腐敗」(rigidity, fragility, immobility, viscosity, needless complexity, needless repetition, opacity)。單元測試是安全重構的基礎。
  3. 軟體設計的「腐敗」與設計原則的必要性:

    • 提供資料指出,軟體設計會隨著時間和需求的變化而「腐敗」,表現為剛性(難以變更)、脆弱性(變更導致意外的錯誤)、不動性(難以重用)、黏滯性(做對的事情比做錯的難)、不必要的複雜性、不必要的重複和不透明性。
    • 敏捷團隊不允許這種腐敗發生,而是持續保持設計的簡單和乾淨。這需要應用物件導向設計原則。原則不是教條,而是在出現「設計的氣味」(design smells)時,用來指導重構以消除這些問題的工具。過度遵守原則也會導致不必要的複雜性。
    • SOLID 原則 (物件導向設計的五項基本原則):
      • SRP (Single Responsibility Principle – 單一職責原則):一個類別或模組只應有一個改變的理由。違反 SRP 會導致職責耦合,變更時影響擴散,系統變得脆弱。應將不同改變理由的職責分離到不同的類別或模組中。
      • OCP (Open-Closed Principle – 開放封閉原則):軟體實體(類別、模組、函數等)應對擴充開放,對修改封閉。這允許在不修改現有程式碼的情況下添加新功能,減少變更帶來的風險。主要透過抽象(介面、抽象類別)和多型實現。閉合是策略性的,針對最可能發生的變更進行設計。
      • LSP (Liskov Substitution Principle – Liskov 替換原則):子型別必須可以在程式中替換其基型別,而不改變程式的正確性。這是 OCP 的基礎,保證了多型替換的行為一致性。定義「IS-A」關係是關於行為,而非僅僅是屬性或外觀。違反 LSP 通常會導致需要 RTTI(執行時類型資訊)檢查,進而違反 OCP。模型的有效性取決於其客戶的合理假設。
      • DIP (Dependency Inversion Principle – 依賴反轉原則):高階模組不應依賴低階模組,兩者都應依賴抽象。抽象不應依賴細節,細節應依賴抽象。這反轉了傳統的依賴方向,使高層次的政策和業務規則不受低層次實現細節的影響,增強了框架的可重用性和系統的靈活性。通常透過介面和抽象類別實現,介面的所有權常常屬於客戶模組。
      • ISP (Interface Segregation Principle – 介面隔離原則):客戶不應被迫依賴他們不使用的介面。這解決了「胖介面」的問題,避免了不必要的耦合。將大型非內聚介面分割成多個客戶特定的、內聚的介面,服務類別可以實作所有相關的隔離介面。這可以通過委託或多重繼承/介面實作來實現。
  4. 設計模式的應用與案例研究:

    • 提供資料通過具體的案例研究(如 Payroll、Weather Station、ETS)展示了如何在實踐中應用上述原則和各種設計模式。
    • Payroll 案例研究: 說明瞭如何從使用者故事出發,透過迭代分析和設計,應用 COMMAND (用於事務處理)、TEMPLATE METHOD (用於支付計算和改變員工屬性)、STRATEGY (用於支付分類、支付方式、工會關聯、支付計畫)、SINGLETON/MONOSTATE (用於確保唯一實例)、NULL OBJECT (用於無關聯狀態) 等模式來構建核心業務模型,並處理需求的變化(如改變支付方式或加入工會)。也說明瞭在設計中推遲細節(如具體資料庫實現)以及如何通過測試反饋來改進設計。後續章節將其組織到套件中,並討論套件設計原則(凝聚性原則 REP, CRP, CCP 和耦合性原則 ADP, SDP, SAP),以及如何運用 Factory 模式管理具體類別的實例化並改善套件依賴結構。
    • Weather Station 案例研究: 展示瞭如何在時間壓力、遺留程式碼、變化需求和平台差異等多重約束下進行設計。說明瞭如何應用 OBSERVER (用於發布感測器讀數)、ADAPTER (用於將不同介面轉換為期望的介面)、BRIDGE (用於分離抽象與實現,如硬體API)、PROXY (用於管理持久化)、FACTORY (用於創建具體實例) 等模式來解耦系統組件、處理不同硬體平台和實現持久化需求。
    • ETS 案例研究: 說明瞭如何從複雜的需求中提煉出可重用的評分框架,並展示瞭如何在 GUI 事件處理和任務管理中應用 FINITE STATE MACHINE (FSM) 和 VISITOR, DECORATOR, EXTENSION OBJECT 等模式來解耦功能、管理狀態轉換和處理多樣化的需求。強調 FSM 在複雜使用者互動和分散式處理中的價值。
  5. 總結:

    • 敏捷軟體開發的成功在於其設計策略:持續的、基於回饋(尤其是來自程式碼和測試)的設計過程。
    • 這個過程的核心是識別設計的「腐敗」,並使用設計原則和模式來消除它。
    • 原則和模式是指導方針和工具,應策略性地應用,而不是不加區別地套用。
    • 設計是一個不斷演進的過程,從初始簡單的結構開始,隨著需求的深入理解和變化,逐步重構和引入更複雜的結構(如模式)。
    • 這種方法使得軟體能夠更好地應對變化,更易於維護和重用,最終提高開發效率和產品品質。

這些論點共同構成《敏捷軟體開發:原則、模式與實踐》前幾個部分所闡述的核心思想,強調了在變動的軟體開發環境中,將設計視為持續改進的活動、重視程式碼品質和依賴管理的重要性。