# 簡介

<img src="../figures/cover.jpeg" style="width: 28%" />

這是一本關於軟體設計的書（英文原名：A Philosophy of Software Design）：如何將複雜的軟體系統分解成模組（比如類和方法），以便這些模組可以相對獨立地實現。本書首先介紹了軟體設計的基本問題，也就是對複雜性的管理，然後討論了一些在完成軟體設計的過程中涉及到的哲學問題，並提出了一系列可以在軟體設計過程中應用的設計原則。本書還介紹了一些可用來識別設計問題的危險訊號。您可以透過應用本書中的想法來減少大型軟體系統的複雜性，以便能更快和更低成本地編寫軟體。

## 目錄

- [前言](preface.md)
- [第 1 章 介紹](ch01.md)
- [第 2 章 複雜性的本質](ch02.md)
- [第 3 章 能工作的程式碼是不夠的](ch03.md)
- [第 4 章 模組應該是深的](ch04.md)
- [第 5 章 資訊隱藏和資訊洩露](ch05.md)
- [第 6 章 通用的模組是更深的](ch06.md)
- [第 7 章 不同的層級，不同的抽象](ch07.md)
- [第 8 章 下沉複雜性](ch08.md)
- [第 9 章 在一起更好還是分開更好？](ch09.md)
- [第 10 章 透過定義來規避錯誤](ch10.md)
- [第 11 章 設計兩次](ch11.md)
- [第 12 章 不寫註釋的四個藉口](ch12.md)
- [第 13 章 註釋應該描述程式碼中難以理解的內容](ch13.md)
- [第 14 章 選取名稱](ch14.md)
- [第 15 章 先寫註釋](ch15.md)
- [第 16 章 修改現有的程式碼](ch16.md)
- [第 17 章 一致性](ch17.md)
- [第 18 章 程式碼應該是易理解的](ch18.md)
- [第 19 章 軟體發展趨勢](ch19.md)
- [第 20 章 效能設計](ch20.md)
- [第 21 章 決定什麼是重要的](ch21.md)
- [第 22 章 結論](ch22.md)
- [總結](summary.md)

## 翻譯說明

原書第二版相對於第一版的內容變更不多，此翻譯版本是在[原書第一版翻譯](https://github.com/yingang/aposd-zh)的基礎上增量更新而來的，而後者的歷史可參見其[翻譯說明](https://github.com/yingang/aposd-zh/tree/main/docs#%E7%BF%BB%E8%AF%91%E8%AF%B4%E6%98%8E)。

第二版的主要變更如下，翻譯自[原作者網站的說明](https://web.stanford.edu/~ouster/cgi-bin/book.php)：
- [第 6 章](ch06.md)（“通用的模組是更深的”）的內容有相對較多的更新。作者自述在第一版出版後，對選擇通用設計的重要性有了更清晰的認識。第 6 章同時也吸收了第一版中第 9.7 節和第 10.9 節的內容。
- [第 9 章](ch09.md)和[第 12 章](ch12.md)增加了一些內容，主要對比了 Robert Martin 所著《程式碼整潔之道》中的設計哲學。作者自述在諸如方法的長度和註釋的作用等方面與對方的觀點有顯著的分歧。
- [第 21 章](ch21.md)（“決定什麼是重要的”）是新增的章節，主要介紹好的軟體設計如何將重要的事情和不重要的事情區分開，並更多關注在重要的事情上。

如果您在閱讀過程中，發現有翻譯不當的地方，或者有其他建議，歡迎提交相應的 PR 或 Issue。

另外，繁體中文的翻譯版本是基於 `opencc` 使用 Python 指令碼自動生成的，如果發現有處理不當的內容，請針對該指令碼或對應的簡體中文內容提交 PR 或 Issue。而英文部分則類似於第一版翻譯，出於尊重原作版權的考慮，刪除了主體部分的內容，只保留了前言、各個章節的概要和總結以及原書第二版相對第一版新增或變更的內容（提取自[原作者網站上開放下載的相關章節](https://web.stanford.edu/~ouster/cgi-bin/aposd2ndEdExtract.pdf)）。

## 術語翻譯

翻譯是個比較困難的事情，除了譯者水平有限，也有很多見仁見智的地方，所以這裡先列出一些術語的翻譯選擇和背後的考慮因素，以供參考，並至少在本書籍的翻譯過程中保持相對統一，也歡迎提 Issue 探討。

|英文|中文|說明|
|-|-|-|
|bug|缺陷 / 程式碼缺陷|沒有用“錯誤”是希望避免與 error 等術語的翻譯混淆|
|change|變更|針對程式碼的時候，更多使用“變更”而不是“改變”，但根據實際的上下文而定|
|clean|整潔的|與《程式碼整潔之道》等系列書籍的翻譯保持一致|
|complexity|複雜性|沒有用“複雜度”，類似的還有“依賴性（dependency）”和“模糊性（obscurity）”|
|deep module / class|深模組 / 深類|沒有用“深層的”是希望避免與 layer 和 level 等術語的翻譯混淆|
|dispatcher|分發器|沒有用“排程器”是希望避免與 scheduler 等術語的翻譯混淆|
|information leakage|資訊洩露|沒有用“洩漏”|
|obvious|易理解的|在描述程式碼的特性時一般會譯為“易理解的”（主要是第 13 章和第 18 章），反之就是“難以理解的”，而其他場景下可能仍譯為“明顯的”或“顯而易見的”|
|pass-through|透傳|用於“透傳方法”、“透傳變數”、“透傳引數”等場景|
|public method / variables|公有方法 / 公有變數|沒有用“公開”是希望避免與 expose 和 exposure 等術語的翻譯混淆|
|selection|區域選擇 / 選擇的區域 / 所選區域|影像介面文字編譯器中的示例，直接翻譯成“選擇”會不太清晰|
|shallow module / class|淺模組 / 淺類|沒有用“淺層的”，和 deep 的翻譯選擇是同樣的原因|
|web browser / server|Web 瀏覽器 / Web 伺服器|沒有用“網路”或“網頁”是希望避免與 network 和 web page 等術語的翻譯混淆，就保留英文了|