軟體設計哲學
作者:Rob Zapp尚無安裝尚無按讚更新於 2026年10月8日分類: 工程
它能做什麼
在撰寫、修改或審查程式碼時使用,當變更新增了可匯出或可匯入的名稱、建立模組、類別、元件、輔助函式、hook、服務或包裝器、集中重複程式碼,或更改 API 時使用。Ousterhout 規則(深層模組、資訊隱藏、降低複雜度)加上共用程式碼的不變測試、讀者成本測試,以及最後必須附上的設計說明。
安裝會在你的 AgentsRoom 桌面版開啟這個條目。如果還沒有安裝應用,你會被帶到下載頁面。
SKILL.md
--- name: 軟體設計哲學 description: 在撰寫、修改或審查程式碼時使用,當變更新增了可匯出或可匯入的名稱、建立模組、類別、元件、輔助函式、hook、服務或包裝器、集中重複程式碼,或更改 API 時使用。Ousterhout 規則(深層模組、資訊隱藏、降低複雜度)加上共用程式碼的不變測試、讀者成本測試,以及最後必須附上的設計說明。 --- # 軟體設計哲學(John Ousterhout) ## 何時使用此技能 當你設計、撰寫、修改或審查程式碼時,使用此技能。它適用於模組設計、API 變更、拆解、重構、命名、註解、測試及效能工作。當變更感覺不自然,或一個變更散布在多個檔案時,也應使用此技能。 ## 需修正的偏誤 可運作的程式碼不等於簡單的程式碼。小片段、熟悉的模式、旗標、包裝器及額外文件可能使設計更複雜。當它們增加讀者必須知道的內容,或當它們將知識洩漏到其他模組時,就會造成複雜性。 ## 決策規則 - 以降低複雜度的程度來衡量設計。偏好能減輕讀者負擔的設計。複雜度有四個徵兆:一個變更需要在多處編輯;依賴關係被隱藏;步驟必須按固定順序執行;讀者必須記住許多事實。 - 將設計視為持續的工作。第一個可運作的補丁若使後續變更更困難,則尚未完成。對介面、模組拆分或抽象的決策,應比較兩個或多個可能的設計。 - 偏好深度模組。深度模組擁有小型介面並隱藏大量複雜性。拒絕傳遞服務、薄型函式庫包裝器及小型輔助模組。拒絕任何只增加名稱但不減輕讀者負擔的抽取。 - 以呼叫者必須知道的內容設計介面,而非實作如何運作。避免脆弱的設定序列、模式旗標、配置旋鈕及顯示內部選擇的參數。 - 隱藏可能改變的決策。例子有內部表示、儲存結構、協定、檔案格式及效能技巧。帳務、正規化及邊緣案例也是例子。將每個決策保留在擁有該知識的模組內。 - 將複雜度拉到擁有細節的模組中。當它能給呼叫者更簡單的契約並移除每個呼叫點的重複工作時,接受較複雜的實作。 - 使模組在適當層級上通用。不要為單一呼叫者量身打造模組。不要為未來需求加入模糊的抽象。將罕見的邊緣案例排除在主要路徑外,並將特殊行為放在自己的位置。 - 以總體複雜度來合併或拆分模組。不要依大小、程式碼執行順序、習慣或外觀來合併或拆分。將相關狀態、行為、規則及決策放在一起。只有當新邊界更深且讀者能獨立理解雙方時才拆分。 - 使例外集合更小。盡可能改變介面或規則,使無效狀態無法發生。不要讓每個呼叫者重複相同的防禦程式碼。 - 使用註解來降低複雜度。寫下介面契約、必須保持正確的規則、隱藏的設計決策及其原因。也寫下呼叫者不必知道的困難事實。不要在註解中重複程式碼。不要用註解掩蓋糟糕的命名、糟糕的拆分或令人困惑的控制流程。 - 將命名、一致性及清晰度視為設計資訊。名稱告訴讀者抽象,而非機制。相關操作使用相同慣例。令人驚訝的程式碼會增加複雜度,即使它很短。 - 針對公開契約及穩定 API 撰寫測試。透過這些契約測試隱藏的複雜度及特殊案例。不要因測試容易而強迫淺層或洩漏的介面。 - 只有出於兩個原因之一,才加入效能變更、模式、範式或框架。它能降低此程式碼庫的複雜度,或證據顯示此權衡是必要的。將每個優化隱藏在穩定介面後。 ## 訊號及對應回應 - 功能不自然,或一個變更散布多個檔案,或審查者必須尋找隱藏依賴。回應:尋找缺失的資訊隱藏及淺層模組。也尋找固定順序的步驟,以及呼叫者攜帶的複雜度。 - 你新增模組、層、服務、輔助、包裝器或外觀。或新增模式、選項、回呼或參數。回應:證明它隱藏的複雜度多於增加的。 - 你變更 API。回應:檢查一般呼叫者必須知道什麼。呼叫者不應需要呼叫順序、表示法或儲存。呼叫者不應需要傳輸、快取、協定或檔案格式。呼叫者不應需要內部工作流程或多個設定步驟。 - 你新增特殊案例、旗標、例外路徑、條件或呼叫者可見的容器。回應:先問擁有模組能做什麼。它可以移除無效狀態、隔離異常行為或提供更強的操作。 - 你拆分程式碼、抽取函式或新增變數。回應:檢查新邊界或名稱是否有意義。它不應只增加跳轉、傳遞狀態或呼叫者可見的中間步驟。 - 程式碼有階段如 `prepare`、`process` 和 `finalize`,或呼叫者必須分階段建立物件。回應:檢查時間順序是否為真正概念。若不是,圍繞穩定責任組織程式碼。 - 名稱模糊、命名機制、不一致或令人驚訝。回應:重新思考抽象邊界。不要接受幾乎正確的名稱。 - 註解冗長、重複程式碼、解釋令人困惑的介面,或顯示內部以說明用法。回應:改變抽象,或將缺失的契約移入介面。 - 你優化效能。回應:先測量,再隱藏優化。沒有證據顯示權衡必要,勿放棄模組深度或資訊隱藏。 - 你測試或審查。回應:查看公開行為及介面契約。也查看穩定 API 背後的隱藏複雜度及抽象後的特殊案例。 ## 最終檢查清單 - 這個變更是否減少了理解、修改、驗證和擴展系統的工作量? - 每個介面元素、包裝器、層、輔助工具、選項和名稱是否隱藏了足夠的複雜度以證明其存在的合理性? - 重要的決策是否集中在一處?依賴關係是否清晰可見?呼叫者需要遵守的限制是否有記錄?可變更的內部實作是否受到保護? - 常見情況是否能在不額外操作的情況下正常運作?罕見的控制、特殊案例、效能技巧和例外細節是否都不會干擾常見流程? - 名稱是否精確且一致?註解是否是最新的,且不重複程式碼內容?程式碼是否遵循現有慣例,除非有新資訊需要更改? ## Gate 當變更新增一個其他程式碼可以匯出或匯入的名稱時,請使用完整檢查清單。當變更建立模組、類別、元件、輔助工具、hook、服務或包裝器,或將重複程式碼集中時,也請使用。重新命名、程式碼轉換、設定變更、資料變更和一行修正則不需要。 ## 不變式測試:只共享會一起變更的程式碼 - 只有當共享程式碼保護一條你能命名的規則時才提取。證據是共同變更:歷史顯示這些複製品是一起修正或變更的。僅看起來相似但獨立變更的程式碼是押韻。押韻就保留為重複。三個相似區塊不代表一條規則。 - 修正必須消除問題,而非移動問題。六個轉型集中到一個通用轉型輔助工具仍是六個轉型。請寫出轉型所隱藏的型別映射器。 - 當抽象錯誤時,將程式碼放回內聯並讓重複回歸。不要用旗標扭曲抽象。 - 不要僅因程式碼大小而拆分。一個 400 行的模組隱藏一個決策,比四個 100 行且洩漏相同連接的模組好。 - 機械式閱讀 Clean Code 或 SOLID(非常小的函式,每個責任一個類別)會產生淺層模組。本技能優先於此壓力。 ## 閱讀成本:第三項測試 深度測試和不變式測試決定邊界是否必須存在。閱讀成本測試決定邊界周圍的程式碼是否容易變更。下一個讀者(人或代理)必須為他們必須閱讀的每一行付出代價。代理以代幣付費。代理透過文字搜尋、部分閱讀、型別檢查和測試來尋找程式碼。 - **可尋找。** 每個概念使用一個名稱。到處拼寫相同,讓純文字搜尋能找到。缺陷:名稱由字串組成、透過匯入副作用接線、同一概念有兩個名稱。隱藏定義的重新匯出鏈也是缺陷。 - **早期停止。** 將契約放在檔案頂端或匯出上方。說明它承諾什麼、隱藏什麼、絕不做什麼。讓讀者能早點停止。 - **機器可檢查。** 在每個邊界輸入和輸出使用精確型別,讓型別檢查取代閱讀呼叫者。缺陷:`any`、純字典、意義只在本體的布林旗標。 - **可見耦合。** 兩處必須一起變更。用共用型別、測試或單一來源強制執行。若無法,兩處都標記。 - **無噪音。** 移除重複程式碼的註解和被註解掉的程式碼。移除死分支和記錄變更歷史的註解。移除舊路徑且不留在替代路徑旁。 - **可預測。** 遵循現有的儲存庫佈局。將測試放在讀者會找的地方,並讓它獨立執行。 檔案大小故意不在此清單中。非常大的檔案是尋找第二個隱藏決策的理由,絕不是拆檔的理由。 ## 安全性 對現有程式碼,先寫測試以維持目前行為,再讓模組更深。對新程式碼,寫定義預期行為的測試。 ## 設計說明(當 gate 適用時必填) 當 gate 適用時,請在 pull request 描述中加入標題為 `## Design note` 的章節。寫兩到四行: - 你新增的每個邊界,以及它隱藏的決策。 - 你故意保留的每個重複,以及原因。 - 你接受的每個淺層部分,以及原因。 若 gate 不適用,請寫 `## Design note`,接著寫 `Gate not applicable: <原因>`。也請將設計說明放在最終步驟的摘要中。 ## 審查模式 當你審查或測試其他代理或人員撰寫的程式碼時使用此章節。 1. 檢查設計說明。當 gate 適用且 pull request 沒有 `## Design note` 章節時,回報阻斷性發現。當說明與差異不符時,回報阻斷性發現。 2. 設計發現只有在同時符合兩個條件時才是阻斷性的: - 它命名了本技能的規則。該規則是決策規則、gate、不變式測試或閱讀成本項目之一。 - 它陳述對讀者或下一次變更的具體成本。範例:「呼叫者必須知道儲存形態。」「一個概念有兩個名稱。」「上限變更需要修改三個檔案。」 3. 將其他所有設計觀察標記為非阻斷性。放在標題為「非阻斷性設計說明」的獨立清單中。非阻斷性說明絕不會將工作退回給建置者。 4. 不要將偏好回報為發現。不同名稱、檔案佈局或風格是偏好。只有當它違反命名規則且有具體成本時,才成為發現。 5. 當相同設計發現於第二次審查循環中再次出現時,請升級處理。不要第三次要求相同變更。 ## 相關技能(安裝時) - `find-shared-code`:僅報告最近歷史中值得共享的程式碼搜尋。使用本技能的不變式測試和深度測試。 - `refactoring` 和 `working-effectively-with-legacy-code`:邁向更深設計的安全步驟。本技能決定新邊界是否保留。 ## 來源與授權 此技能建立於 GitHub 上 ciembor/agent-rules-books 倉庫中《A Philosophy of Software Design》的「迷你」規則(MIT 授權,提交版本 893a88a)。閘門、不變式測試、讀者成本測試、設計註記與審查模式是對這些規則的補充。該倉庫也包含了該書的完整規則。
標籤
設計架構ousterhout審查
延伸閱讀
Claude Ads:幫你審計廣告帳戶的 Claude Code 技能
Claude Ads 是一款面向 Claude Code 的開源技能:對 Google、Meta、LinkedIn、TikTok、Amazon 廣告等做 250 多項檢查,給出百分制評分和按優先順序排序的行動方案,全程只需十來分鐘。本文講解安裝、命令、侷限,以及如何在 AgentsRoom 中把它編排起來。
AGENTS.md:一個上下文檔案餵飽所有編碼 Agent(Codex、Antigravity、Claude)
AGENTS.md 是 AI 編碼 Agent 在動你程式碼之前先讀的那份可移植指令檔案。該往裡寫什麼、它和 CLAUDE.md 有何區別,以及如何在 Codex、Antigravity 和 Claude 之間保持同一份上下文。
下載 AgentsRoom
在一個視窗中執行你所有專案的所有 AI 代理。
免費下載 AgentsRoom
配套應用:隨時隨地監控你的 Agent
使用 Claude、Codex、Antigravity CLI 或其他 AI 提供商。
獲取擴充功能
Chrome Web Store
把 Bug 和需求直接傳送到您的公開待辦清單。