全端設計模式指南
使用此技能來建議、架構和重構端到端的全端系統。嚴格根據可識別的架構摩擦來套用模式,而非進行投機的抽象化。
核心原則
- 問題優先選擇: 絕不引入沒有明確架構摩擦或程式碼壞味道的設計模式(例如,prop drilling、臃腫的 god-component、緊密的 API 耦合、無法測試的邏輯、階梯式的網路故障)。
- 清晰的架構縫隙: 維持下列各層之間的清晰邊界:
- 檢視 / 呈現層: 由 props 驅動的啞巴、宣告式元件。
- 客戶端狀態與互動層: 無頭 hooks、集中式儲存、伺服器狀態快取。
- API / 契約層: 型別化 schema、DTO 適配器、防腐層。
- 領域與資料存取層: 解耦的業務規則與儲存庫支援的資料庫存取。
- 避免過度工程化: 不要對簡單的 CRUD 頁面或標準網頁應用程式套用複雜的企業級抽象化(如微前端、CQRS 或分散式發佈/訂閱)。
模式決策矩陣與觸發啟發法
| 層 | 程式碼庫中的症狀 / 摩擦 | 建議模式 | 架構縫隙 |
|---|---|---|---|
| 前端 UI | God-component 混合了 API 擷取、格式化和 JSX 佈局 | 容器 / 呈現元件 | 將 UI 渲染與資料擷取分離 |
| 前端 UI | 互動式元件(模態框、下拉選單)內緊密耦合的樣式 | 無頭元件 / 自訂 Hooks | 隔離狀態與鍵盤/互動邏輯 |
| 前端 UI | 需要彈性子元素的僵化元件 API | 複合元件 | 宣告式的父子狀態共享(例如,Tabs、Select) |
| 前端 UI | 深層 prop drilling 或多元件 UI 狀態不同步 | 觀察者 / 儲存(Zustand/Redux/Context) | 集中管理共享的客戶端狀態 |
| 全端 API | 後端 API schema 變更破壞前端 UI 元件 | 適配器模式(資料映射器) | 將 DTO 轉換為檢視模型的防腐層 |
| 全端 API | UI 在確認使用者操作前需等待緩慢的網路 | 樂觀更新與回滾 | 由交易回滾支援的即時 UI 回應 |
| 後端 | SQL/ORM 查詢散落在路由處理器或服務中 | 儲存庫模式 | 將持久化查詢與業務規則解耦 |
| 後端 | 使用內聯 if-else 實例化不同的第三方 SDK | 工廠模式 | 集中管理物件與客戶端建立 |
| 後端 | 計算定價、授權或演算法時出現階梯式 if-else / switch | 策略模式 | 將可互換的演算法封裝在介面之後 |
| 後端 / 分散式 | 核心業務動作觸發了 5 個以上不相關的副作用 | 觀察者 / 事件驅動(發佈/訂閱) | 透過領域事件或訊息佇列解耦副作用 |
| 後端 / 分散式 | 外部 API 延遲導致執行緒耗盡與串聯式停機 | 斷路器模式 | 快速失敗、回退回應與下游健康檢查 |
深入探討:全端模式與實作規則
1. 前端:容器 / 呈現元件模式
- 情境: 元件因結合
useEffect、查詢、資料轉換和佈局 JSX 而超過 200 行。 - 規則:
- 呈現元件: 僅透過 props 接收資料和回呼;純淨,可在無需 API mock 的 Storybook 中輕鬆測試。
- 容器(或頁面 Hook): 擷取伺服器資料,管理載入/錯誤狀態,並將轉換後的資料傳遞下去。
2. 前端:無頭元件與自訂 Hook 模式
- 情境: 需要跨不同視覺設計重複使用的複雜互動行為(自動完成、多步驟精靈、手風琴)。
- 規則:
- 將狀態、鍵盤處理程式和 ARIA 屬性提取到一個無頭自訂 hook 中(例如,
useAutocomplete、useDisclosure)。 - 將樣式和 DOM 標記完全保留在消費者的手中。
- 將狀態、鍵盤處理程式和 ARIA 屬性提取到一個無頭自訂 hook 中(例如,
3. 前端:複合元件
- 情境: 具有深度相關子部分的元件,需要凝聚的內部狀態,而無需傳遞數十個配置 props。
- 規則:
- 利用 React Context 在父元件和子元件之間隱式通訊(
<Accordion><Accordion.Item /><Accordion.Panel /></Accordion>)。
- 利用 React Context 在父元件和子元件之間隱式通訊(
4. 整合:適配器模式(防腐層)
- 情境: 第三方 REST/GraphQL 負載直接洩漏到 UI 元件 props 或核心領域模型中。
- 規則:
- 絕不讓原始的後端 DTO 鍵值決定前端元件的 prop 形狀。
- 建立明確的映射器函式(例如,
toUserViewModel(dto: UserApiDto): UserVM)來保護 UI 元件免受 schema 變更的影響。
5. 整合:樂觀更新與回滾
- 情境: 頻繁的使用者互動(按讚、切換、任務完成、重新排序),其中網路延遲會影響回應速度。
- 規則:
- 互動後立即更新本地狀態。
- 將伺服器變更排入佇列;如果被拒絕,則回滾到先前的快照並以非侵入式方式通知使用者。
6. 後端:儲存庫模式
- 情境: 業務邏輯與 ORM 查詢(Prisma、TypeORM、Drizzle、SQL)交織在一起。
- 規則:
- 服務僅透過介面(例如,
OrderRepository)進行互動。 - 將領域邏輯保留在儲存庫之外;將查詢建構保留在服務之外。
- 服務僅透過介面(例如,
7. 後端:策略與工廠模式
- 情境: 可互換的提供者(支付閘道、通知通道、檔案儲存)。
- 規則:
- 透過通用介面(
PaymentGateway)標準化行為。 - 使用工廠/註冊表根據配置或租戶解析具體實作。
- 透過通用介面(
8. 後端:斷路器模式
- 情境: 外部微服務或第三方 API 遭遇間歇性停機或嚴重延遲。
- 規則:
- 追蹤故障閾值。狀態轉換:
Closed(正常)->Open(快速失敗,回傳快取/備用)->Half-Open(金絲雀探測)。
- 追蹤故障閾值。狀態轉換:
代理輸出工作流程
當被要求對架構提供建議或重構全端程式碼時:
- 識別縫隙與瓶頸: 確定摩擦點是在 UI 渲染、狀態同步、API 契約不匹配還是後端耦合。
- 選擇匹配模式: 提出模式,並提供清楚的理由來說明它如何解決特定的程式碼壞味道。
- 提供重構前/後範例: 提供簡潔、慣用的程式碼片段,展示解耦後的責任分工。
- 強調可測試性與可維護性: 解釋重構如何簡化單元/元件測試,並保護系統免受未來變更的影響。