Swift Redux 架構完整指南:從 Reducer 到 Middleware 的狀態管理實踐

引言:為什麼需要 Redux? 在 iOS 開發中,隨著應用規模擴大,狀態管理逐漸成為最具挑戰性的課題。當多個 View 需要共享狀態、狀態變化難以追蹤時,應用很容易陷入混亂。 Redux 作為一種可預測的狀態容器,最早在 JavaScript 生態系中流行,如今也廣泛應用於 Swift/iOS 專案。本文將深入介紹 Redux 架構的核心觀念,包含: Reducer(減少器):狀態更新的核心邏輯 Store(儲存區):應用的單一狀態來源 Action(動作):描述「發生什麼事」的指令 Middleware(中介層):處理非同步與副作用 Redux 核心架構概覽 架構組成 架構特性: ✅ 單向資料流:資料流向可預測 ✅ 單一狀態來源:整個應用只有一個 State 樹 ✅ 狀態不可變:不直接修改 State,而是創建新 State ✅ 可測試性高:Reducer 是純函數,易於測試 核心概念 1:State(狀態) State 是什麼? State 是整個應用的單一資料來源(Single Source of Truth)。它通常是一個 struct,描述當前應用的完整狀態。 實作範例 // AppState.swift struct AppState { // 購物車 var cartItems: [CartItem] = [] var totalAmount: Decimal = 0.0 // 用戶資訊 var userProfile: UserProfile? var isLoggedIn: Bool = false // UI 狀態 var isLoading: Bool = false var errorMessage: String? // 套餐選擇 var packages: [Package] = [] var selectedPackageId: String? } // 購物車商品 struct CartItem: Identifiable { let id: String let name: String let price: Decimal var quantity: Int } // 用戶資料 struct UserProfile { let id: String let name: String let email: String } // 套餐 struct Package: Identifiable { let id: String let name: String let items: [PackageItem] } struct PackageItem: Identifiable { let id: String let name: String var quantity: Int } 設計原則: ...

August 21, 2025 · 10 分鐘 · Peter

Flutter 狀態監聽完全指南:Provider、Bloc、Riverpod、GetX 深度比較

前言:Flutter 狀態管理的核心挑戰 在 Flutter 開發中,狀態管理是最重要也最複雜的主題之一。當應用程式規模增長,Widget 樹層級加深,如何讓不同層級的 Widget 能夠正確地監聽和響應狀態變化,成為每個 Flutter 開發者必須面對的挑戰。 選擇錯誤的狀態監聽方式,會導致: ❌ 不必要的重繪:整個 Widget 樹被重建,效能下降 ❌ 記憶體洩漏:忘記釋放監聽器,導致記憶體持續增長 ❌ 狀態不同步:多個 Widget 顯示不一致的資料 ❌ 程式碼難以維護:狀態邏輯散落各處,難以追蹤 本文涵蓋內容 本文將深入探討 Flutter 四大主流狀態管理方案的監聽機制: Provider:Flutter 官方推薦的輕量級狀態管理 Bloc:基於 Stream 的企業級狀態管理 Riverpod:Provider 的改進版本,解決了 Provider 的核心問題 GetX:高效能的響應式狀態管理 我們將從實際問題出發,比較這四種方案的: 🔍 核心原理:底層如何實現狀態監聽 💻 實戰範例:可執行的完整程式碼 ⚡ 效能表現:重繪範圍、記憶體使用 🎯 適用場景:什麼情況下使用哪種方案 ⚠️ 常見陷阱:實戰中容易踩的坑 Provider 狀態監聽機制 Provider 是 Flutter 官方推薦的狀態管理方案,基於 InheritedWidget 實現。它的核心優勢是簡單易用,適合中小型應用。 Provider 核心概念 Provider 使用 依賴注入 (Dependency Injection) 和 作用域 (Scope) 的概念來管理狀態: 關鍵概念: Provider 有作用域限制:只有在 Provider 子樹內的 Widget 能存取狀態 三種存取方式:context.watch()、context.read()、context.select() 自動重繪機制:使用 watch 時,狀態改變會自動觸發 Widget 重繪 實戰問題:跨路由讀取 Provider 這是我在開發中遇到的真實問題: ...

July 13, 2023 · 15 分鐘 · Peter