###### tags: `讀書會` `Clean Code` `JavaScript`
# [讀書共筆] Clean Code 學派的風格實踐
[TOC]
Section 1:Clean Code是什麼?
===
## Chapter 1:背景說明
作者根據 Robert C. Martin 的[《無暇的程式碼》](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882),撰寫一份適用於 JavaScript 的原則。本文不是風格指南(Style Guide),而是教導你撰寫出[可閱讀、可重複使用與可重構](https://github.com/ryanmcdermott/3rs-of-software-architecture)的 JS 程式碼。
注意!你不必嚴格遵守每一項原則,有些甚至不被大眾所認同。雖然這只是份指南,卻是來自《無暇的程式碼》作者的多年結晶。
軟體工程只發展了五十年,仍然有很多地方值得去探討。當軟體與建築一樣古老時,也許會有一些墨守成規的原則。但現在,先讓這份指南當試金石,作為你和團隊的 JS 程式碼標準。
還有一件事情:知道這些原則,並不會立刻讓你成為出色的開發者,長期奉行它們,不代表你能高枕無憂不再犯錯。但是,千里之行,始於足下,時常與志同道合們進行討論(Code Review),改善不完備之處。不要因為自己寫出來的程式碼很糟糕而害怕分享,而是要畏懼自己居然寫出了這樣的程式碼!
### 我們為何撰寫程式碼?
程式碼是一種解決問題的方式,可用來傳遞資訊和意圖。
人們透過「高度明確和標準化的方式」明確「指示」機器執行每個步驟,以確保指令會每次都按預期執行。
如果不考慮使用者,寫程式將不具意義。重要的是考慮程式碼的所有使用情形,想像「程式設計師」或「終端使用者」會如何使用,以及對它會有什麼樣的期望。
問題探討:
+ 使用者正面臨什麼問題
+ 他們目前如何執行這項任務?
+ 有哪些現有的解決方案,以及它們如何運作?
我們建立的「問題模型」,或稱「概念模型」,將決定最終編寫的程式碼。
失敗的第一步通常是誤解問題,進而導致實作錯誤的解決方案。要想設計一個良好的問題解決方案,關鍵在於需要「正確且完整」」的問題領域,封裝了使用者遇到的問題、技術所能支援且是使用者需求的問題。
### 為人們編寫程式碼
我們編寫的程式碼主要是為了人們,包括 GUI 終端使用者、程式設計師,或是未來的自己。
針對設計程式碼的「可理解性」,和「結構」一樣重要。我們首先應該注意其「可讀性」和「表示方式」,而「一致性」是其中的關鍵部分。
我們在編寫的每一行程式碼中,透過不斷使用和建立「抽象型態」,在處理複雜事物時,以一種更簡單的方式去存取原本的複雜事物,而不需擔心電腦運行的細節。
抽象塔是一種查看技術複雜性的方法,階層由高到低如下所示:
+ Web 應用程式
+ Codebase 程式庫
+ Framworks 框架 / 程式語言
+ Browser 瀏覽器 / 執行狀態
+ Operating System 作業系統
+ Hardware 硬體機制
### 問題討論
---
## Chapter 2:Clean Code 的宗旨
編寫程式碼的核心在於傳達意圖,好的軟體需涵蓋四個核心原則:可靠性、效率、可維護性、可用性,但這些原則並非規則,我們可將它們視為檢視程式碼的依據。
### 可靠性 reliability
指的是可靠的品質,可透過三種不同的品質來定義:
+ 正確的 correct
+ 了解「要解決的問題」以及「使用者需求」
+ 優化需求,直到需求變得更明確
+ 測試程式碼以驗證其正確性
+ 例如:自行編寫電子郵件驗證功能需考慮許多例外情況(edge cases),我們可透過使用現有的、且經過「反覆測試」(tried-and-tested)的開放原始碼函式庫及實用程序來達成
+ 穩定的 stable
+ 在給定不同輸入和情況下,能夠表現持續的正確行為
+ 透過測試來確認其穩定性
+ 例如:不同的作業系統、不同行動裝置、不同的瀏覽器
+ 具有彈性的 resilient
+ 探討程式碼遭遇意外或非常規輸入的情況,也稱作「容錯能力」(fault tolerance)
+ 透過適度降級來實現彈性
+ 例如:電扶梯,即使系統發生意外故障,使用者仍可在電扶梯上下移動
### 效率 efficiency
+ 時間:注意勿對程式碼進行「微優化」,必須先評估程式碼效能,研究實際存在的效能瓶頸
+ 空間:只做必要的事情、避免浪費,節省可用的資源
+ 效率的影響:需考量所做選擇的連鎖效應(knock-on effects)
### 可維護性 maintainability
+ 能夠對程式碼進行修改的簡便性
+ 為了迎合其他程式設計師
+ 適應性 adaptability
+ 程式碼適應不同需求和環境的能力
+ 可藉由將不同功能進行模組化,避免程式碼路徑相互交錯
+ 熟悉性 familiarity
+ 透過使用熟悉的規範和直觀的模式,確保開發者之間的共識
+ 可參考以下指引:
+ 不偏離常見的設計模式
+ 語法和表達保持一致
+ 澄清不熟悉的問題領域
### 可用性 usability
+ 對使用者而言是有用且易於使用的
+ 為了迎合所有使用者,又可分成兩大類:
+ 透過介面使用程式碼功能的人
+ 對程式碼進行修改已完成新任務或修復錯誤的人
+ 易於理解的問題模型 + 明確的需求 = 使用者故事
+ 幫助定義要滿足的目的
+ 作為一個 {`角色`},我想{`想要做`},以便{`目的`}
+ 輔助性 = 無障礙 = 可及性
+ W3C 發布的 Web 內容輔助性指引,包括以下規定:
+ 提供任何非文字內容的替代物
+ 透過鍵盤提供所有功能
+ 使文字內容可讀易懂
### 小結
+ 這些原則看起來很複雜,總之遵循一個規則——始終關注於使用者(always focus on the user)就對了!
---
## Chapter 3:Clean Code 的敵人
### 敵人 #1-JavaScript
### 敵人 #2-管理 Management
### 敵人 #3-自我 Self
### 敵人 #4-貨物崇拜 cargo cult
---
## Chapter 4:SOLID 及其他原則
### Demeter 定律
### SOLID
### 抽象原則
### 函數式程式設計原則
---
## Chapter 5:命名很困難
### 名稱中有什麼?
### 命名反模式
### 一致性和層次結構
### 技術和考量
---
Section 2:JavaScript和它的位元
===
## Chapter 6:原始類型和內建類型
### 原始類型
### 物件
### 函數
### 陣列和可迭代
### RegExp
---
## Chapter 7:動態類型化
### 檢測
### 轉換、隱式強制轉換、顯式強制轉換
---
## Chapter 8:運算子
### 運算子是什麼?
### 算術和數字運算子
### 邏輯運算子
### 比較運算子
### 賦值運算子
### 屬性存取運算子
### 其他運算子和語法
### 位元運算子
---
## Chapter 9:語法和作用域
### 表達式、敘述句和區塊
### 作用域和宣告
---
## Chapter 10:控制流程
### 控制流程是什麼?
### 命令式與宣告式程式設計
### 控制權的移動
### 控制流程的敘述句
### 處理循環複雜度
### 異步控制流程
---
Section 3:製作抽象
===
## Chapter 11:設計模式
### 設計師的觀點
### 架構模式
### JavaScript模組
### 模組化設計模式
### 規劃與和諧
---
## Chapter 12:真實世界的挑戰
### DOM和單頁應用程式
### 依賴性管理
### 安全性
---
Section 4:測試和工具
===
## Chapter 13:測試環境
### 測試是什麼?
### 測試的類型
### 測試驅動開發(TDD)
---
## Chapter 14:編寫乾淨的測試
### 測試正確的事情
### 編寫直觀的斷言
### 建立清晰的層次結構
### 提供最終的明確性
### 建立乾淨的目錄結構
---
## Chapter 15:讓程式碼更無瑕的工具
### linter和格式化程序
### 靜態類型化
### E2E測試工具
### 自動化建構和CI
---
Section 5:合作與做出改變
===
## Chapter 16:將你的程式碼文件化
### 乾淨文件的內涵
### 文件無所不在
### 為非技術讀者寫作
---
## Chapter 17:其他人的程式碼
### 繼承程式碼
### 處理第三方程式碼
---
## Chapter 18:溝通與倡導
### 規劃和設定需求
### 溝通策略
### 找出問題並推動變革
---
## Chapter 19:案例研究
### 問題
### 設計
### 實作
---
## 參考資料
+ [GitHub 範例程式碼](https://github.com/PacktPublishing/Clean-Code-in-JavaScript)
{"metaMigratedAt":"2023-06-16T04:09:44.029Z","metaMigratedFrom":"YAML","title":"[讀書共筆] Clean Code 學派的風格實踐","breaks":true,"disqus":"HackMD","contributors":"[{\"id\":\"bef73355-7ee2-4b0e-8221-dd8a26de937c\",\"add\":14,\"del\":24},{\"id\":\"880be0cd-b3f2-45b4-af6d-177111b45b50\",\"add\":3724,\"del\":252}]"}