7 Coding Patterns I Stole From Senior Engineers
原始來源與檔名:2026-06-16T094218+0800-7 Coding Patterns I Stole From Senior Engineers.md
NAPKIN | 餐巾纸
餐巾纸公式
高手程式碼 = (提早返回 + 業務命名 + 邊界隔離 + 嚴謹狀態 + 分離決策) × 易讀性
好程式碼不是炫技,而是為了讓下一個接手的人減少猜測。
一句话
資深工程師的程式碼之所以無聊,是因為他們把複雜性鎖在清晰的邊界內,而不是讓它蔓延到別人的大腦裡。
餐巾纸草图
[複雜的外部世界 / API]
|
(3. 邊界隔離)
V
[清晰的內部領域模型]
|--- (4. 嚴謹的狀態設計)
|--- (2. 具備業務意義的命名)
V
[業務決策邏輯] <--- (5. 分離決策與行動) ---> [副作用/執行行動]
|
(1. 提早返回,過濾無效狀態)
V
[清晰且有用的錯誤日誌] (6. 錯誤對下一個人有用)
ROUND 1: SKELETON | 骨架掃描
“這本書在說什麼”
- 核心問題: 資深工程師到底如何寫出能夠在生產環境中存活的程式碼?
- 核心答案: 他們不是使用更酷炫的語法,而是撰寫「無聊」的程式碼,不給下一個人製造麻煩。
- 論證結構: 案例型與對比型 (比較菜鳥寫法與老手寫法的差異)。
章節骨架
- 提早返回 (Return Early): 移除無效路徑,讓核心邏輯浮現。
- 業務命名 (Business Meaning): 用業務意義命名,而非技術載體。
- 邊界隔離 (Boundaries): 不讓外部系統定義內部資料形狀。
- 嚴謹狀態 (Invalid States): 用型別讓無效狀態難以存在。
- 分離決策與行動 (Separate Decisions): 抽離決策邏輯,使其易於單元測試。
- 有用的錯誤 (Useful Errors): 錯誤訊息是寫給除錯者和系統看的。
- 優化審查 (Optimize for Diff): 專注於 PR 的易讀性與可回溯性。
ROUND 2: DISSECTION | 血肉解剖
“憑什麼這麼說”
論證鏈
程式碼主要成本在於閱讀與除錯 --> 複雜且模糊的結構會增加認知負擔 --> 資深工程師透過一系列模式 (提早返回、業務命名、防禦型狀態等) 降低認知負擔 --> 因此程式碼更穩定且易於維護
關鍵證據
- 巢狀條件災難:多層 if 判斷隱藏了真實的業務邏輯,提早返回可立即曝露錯誤路徑。
- 外部依賴蔓延:如果直接使用第三方 API 的欄位名稱(如
response.data.user_name),一旦 API 改變,整個程式碼庫都會崩潰;而映射層能控制爆炸半徑。 - 狀態不一致:將所有欄位設為 Optional 只是掩耳盜鈴,建立如
DraftUser和SavedUser的嚴謹型別,能在編譯期就攔截邏輯漏洞。
隱形假設與邊界
- 隱形假設:
- 程式碼的閱讀次數遠大於撰寫次數。
- 測試與可維護性比少寫幾行程式碼更重要。
- 邊界條件:
- 在極小型的拋棄式腳本中,嚴格的邊界隔離可能是過度設計 (Over-engineering)。
- 某些特定的樹狀遍歷或解析器確實需要巢狀結構。
ROUND 3: SOUL | 靈魂提取
“還能怎麼用”
- 作者盲點: 雖然提到了這些模式,但並未深入探討如何將這些模式與團隊的 CI/CD 或程式碼審查自動化工具結合。
- 知識連接: 這些模式與《Clean Code》(無瑕的程式碼) 和《Domain-Driven Design》(領域驅動設計) 中的防腐層 (Anti-corruption Layer) 概念高度一致。
- 行動觸發: 下次提交 PR 之前,檢查是否將重構與新功能混在一起,並確保自己撰寫的錯誤日誌能讓半夜起床值班的同事一眼看懂。
跨域映射
- 在 領域驅動設計 (DDD),這叫 防腐層 (Anti-corruption Layer)(對應邊界隔離)。
- 在 函數式編程 (FP),這叫 純函數與副作用分離(對應分離決策與行動)。
7 Coding Patterns I Stole From Senior Engineers (Architectural Deep Dive)
前言/背景
這篇文章探討了資深工程師與初階開發者在撰寫程式碼時的根本差異。作者指出,資深工程師之所以優秀,並非因為他們掌握了更多酷炫的語法或框架技巧,而是因為他們專注於「減少驚嚇 (Reduce surprise)」。他們透過七種實用的程式碼設計模式,將系統的複雜度封裝在可控的範圍內,使程式碼在面臨需求變更或生產環境事故時,依然具備極高的可維讀性與可維護性。
章節詳細總結
1. 提早返回 (Return Early) 替代巢狀條件迷宮
初階開發者經常習慣將業務邏輯寫在層層遞進的 if 條件中,導致核心邏輯深陷在巢狀結構內,這被稱為「條件迷宮 (Conditional Mazes)」。資深工程師則採用「Guard Clauses (守衛子句)」,優先排除無效或錯誤的執行路徑,讓正常的業務邏輯 (Happy Path) 能夠在最外層清晰展開。
技術細節與程式碼展示: 與其撰寫層層嵌套的結構,不如提早拋出錯誤:
async function updateUserProfile(userId: string, input: ProfileInput) {
const user = await getUser(userId);
// 提早返回:過濾無效狀態
if (!user) throw new NotFoundError("User not found");
if (!input.email) throw new ValidationError("Email is required");
if (!user.canEditProfile) throw new ForbiddenError("User cannot edit profile");
// 核心業務邏輯直接浮現
return saveProfile(user.id, input);
}
架構意義:這符合「Fail Fast」原則。在處理生產環境事故時,工程師能依序且直觀地理解「什麼情況會阻止程式執行」,而不需要在腦海中維持複雜的條件狀態樹。
2. 基於業務意義命名 (Name the Business Meaning)
許多開發者習慣使用 data、result、payload 或 item 這些反映技術載體的詞彙來命名變數。然而,當系統變大時,這些詞彙會失去上下文,導致語義不清(例如 activeUsers 可能包含被停權但未刪除的用戶)。
技術細節與程式碼展示:
// 菜鳥寫法:只表達了這是一個結果與狀態
const result = await getData(id);
if (result.status === "active") {
await process(result);
}
// 資深寫法:表達了領域模型與業務意圖
const subscription = await getSubscription(subscriptionId);
if (subscription.isBillable) {
await chargeSubscription(subscription);
}
架構意義:良好的命名本身就是一種防禦性設計,它創造了「誤用的摩擦力」。在微服務架構或領域驅動設計中,使用 Ubiquitous Language (通用語言) 能夠確保技術實作與業務邏輯的緊密對齊。
3. 建立外部混亂的隔離邊界 (Boundaries Around External Chaos)
第三方 API、Webhook 或是外部資料庫的結構是不穩定的。如果讓外部系統的資料結構(如 response.data.user_name)直接滲透到核心業務邏輯或 UI 層,那麼第三方系統的任何變更都會引發全域性的重構。
技術細節與程式碼展示: 資深工程師會在系統邊界建立映射層 (Mapping Layer) 或防腐層 (Anti-corruption Layer):
// 建立邊界,將外部的蛇形命名與不穩定結構,轉換為內部控制的領域模型
function mapBillingCustomer(response: BillingCustomerResponse): Customer {
return {
id: response.id,
name: response.user_name,
isBillable: response.status === "ACTIVE",
planName: response.subscription?.plan_name ?? "Free"
};
}
架構意義:「永遠不要讓你無法控制的系統,來定義你能控制的系統的形狀」。這有效控制了爆炸半徑 (Blast Radius),當第三方 API 升級或欄位變更時,只需要修改這個轉接器 (Adapter/Mapper) 即可。
4. 讓無效狀態難以存在 (Make Invalid States Hard)
為了讓編譯器 (如 TypeScript) 不報錯,開發者常將所有屬性設為可選 (?),這導致整個系統充滿了對 null 或 undefined 的猜忌與防禦性檢查。
技術細節與程式碼展示: 與其使用一個充滿 Optional 的泛用型別,不如誠實地建模不同的業務狀態:
// 定義不同生命週期的精確狀態
type DraftUser = { email: string; role: "admin" | "member"; };
type SavedUser = { id: string; email: string; role: "admin" | "member"; status: "active" | "disabled"; };
// 使用 Discriminated Unions 處理複雜狀態
type Payment =
| { state: "pending"; id: string }
| { state: "authorized"; id: string; authorizationId: string }
| { state: "captured"; id: string; receiptId: string }
| { state: "failed"; id: string; reason: string };
// 函數簽名直接要求特定的安全狀態
function sendReceipt(payment: Extract<Payment, { state: "captured" }>) {
return emailReceipt(payment.receiptId);
}
架構意義:這是「Parse, don’t validate」理念的延伸。在型別系統層面消滅不合法的狀態組合,可以大幅減少執行期的 Bug (如對尚未授權的付款進行退款)。
5. 分離決策與行動 (Separate Decisions From Actions)
將「判斷邏輯」與「副作用 (如資料庫寫入、發送 API、寄送 Email)」混在一起,會使得單元測試變得極其困難,因為你必須 Mock 大量的外部依賴。
技術細節與程式碼展示: 將決策抽離成純函數 (Pure Function):
// 決策層:純函數,極易進行單元測試
function getRefundEligibility(invoice: Invoice): RefundEligibility {
if (invoice.status !== "paid") return { allowed: false, reason: "Invoice is not paid" };
if (invoice.refundedAt) return { allowed: false, reason: "Invoice is already refunded" };
if (invoice.amount <= 0) return { allowed: false, reason: "Invalid refund amount" };
return { allowed: true };
}
// 行動層:只負責執行決策與副作用
async function refundInvoice(invoiceId: string) {
const invoice = await getInvoice(invoiceId);
const eligibility = getRefundEligibility(invoice); // 調用決策
if (!eligibility.allowed) throw new ValidationError(eligibility.reason);
await paymentProvider.refund(invoice.paymentId);
await markInvoiceRefunded(invoice.id);
}
架構意義:這是命令與查詢職責分離 (CQRS) 和六角架構的核心精神。將核心業務規則與副作用隔離,不僅提高了可測試性,也讓規則更具可重用性。
6. 提供有用的錯誤訊息 (Make Errors Useful)
拋出 { "message": "Something went wrong" } 是一種災難,因為它對後端除錯、前端狀態展示和維運監控都毫無幫助。文字訊息是給人類看的,系統應該依賴結構化的代碼 (Codes)。
技術細節與程式碼展示: 優秀的錯誤響應應該包含結構化的錯誤碼與上下文:
{
"code": "USER_EMAIL_ALREADY_EXISTS",
"message": "A user with this email already exists.",
"details": { "field": "email" },
"requestId": "req_8f91a2"
}
在後端日誌中:
// 記錄充分的上下文,但絕不記錄敏感資訊 (如密碼、信用卡號)
logger.warn("Refund rejected", {
invoiceId,
customerId,
reason: eligibility.reason,
requestId
});
架構意義:這增強了系統的可觀測性 (Observability)。透過RequestId 串聯分散式追蹤 (Distributed Tracing),讓排查生產環境問題從「通靈猜測」變成「精準定位」。
7. 針對差異優化,而非演示 (Optimize for the Diff, Not the Demo)
初階工程師追求在本地端把功能跑通就好,經常提交包含重構、新功能、修正 Bug 以及格式調整的「巨大 PR (Pull Request)」。資深工程師知道程式碼審查 (Code Review) 和回滾 (Rollback) 的成本,因此他們優化的是「Diff 的可讀性」。
技術細節與程式碼展示: 將巨大的變更拆分為微小且獨立的 PR 序列:
- PR 1: 無行為變更的欄位重命名
- PR 2: 新增退款資格的邏輯與測試 (不影響現有流程)
- PR 3: 將退款邏輯接入計費流程
- PR 4: 更新儀表板 UI
架構意義:這不僅是 Git 工作流的最佳實踐,更是維持高頻率部署與降低回滾風險的核心。將基礎設施重構與業務邏輯變更分開提交,能保證 CI/CD 流程的順暢與安全。
總結與結論
- 建立領域防腐層:外部 API 與資料庫定義是極度不穩定的。在系統邊界建立映射層 (Mapping Layer) 可以將第三方依賴的爆炸半徑控制在單一轉接器內,保護核心業務邏輯的純潔性。
- 運用型別系統推演狀態機:不要濫用 Optional 屬性。利用型別系統(如 Discriminated Unions)精確描述領域模型在不同生命週期下的狀態,這能將絕大多數的運行時錯誤 (Runtime errors) 提前在編譯期攔截。
- 擁抱純函數以提升可測試性:將業務「決策 (Decision)」與「副作用 (Action)」嚴格分離。這不僅消除了大量複雜且脆弱的 Mock 測試,更能確保核心業務規則能夠被獨立、充分地驗證。
- 可觀測性從錯誤設計開始:錯誤處理不是事後補救,而是 API 設計的一環。利用標準化的錯誤碼與夾帶 RequestID 的上下文日誌,是建構高可用分散式系統的基石。