iT邦幫忙

2025 iThome 鐵人賽

DAY 1
0

大家好,歡迎來到「Crew Up!」的架構之旅!

在接下來的 30 天,我們將從零開始,一步步打造一個名為「Crew Up!」的社交 APP。這不只是一個教學,更是一份開發日誌,記錄我們如何用專業、嚴謹的態度,去思考、設計、並實作一個真實世界的應用。

許多教學的第一步都是 flutter create,然後直接跳進 UI 開發。但對一個專業工程師來說,真正的第一步,發生在輸入指令之後:
選擇一個能支撐我們走完全程的「架構」

這就像是「都市計畫」。你可以隨意地在一塊空地上蓋一棟小茅屋,但如果你想建造一座能容納百萬人口、持續發展數百年的大都會,你就必須先做好都市計畫:劃分商業區、住宅區、工業區,並設計好它們之間的交通幹道。軟體架構,就是我們 APP 的「都市計畫」。

在動手寫任何一個 Widget 之前,先決定架構,是為了避免未來幾週、甚至幾個月的混亂。我們都可能經歷過這樣的專案:一開始功能很簡單,所有程式碼都寫在一起。但隨著需求增加,這個檔案變成數千行的「巨獸 (Monster)」,改一個小地方就可能引發連鎖反應,沒人敢動它。這就是缺乏架構的代價。

一個好的架構,能在以下幾個關鍵點上幫助我們:

  • 關注點分離 (Separation of Concerns): 將 UI、商業邏輯、資料處理明確分開,讓不同職責的程式碼互不干擾
  • 管理複雜性 (Managing Complexity): 透過模組化,將複雜的大問題拆解成可獨立解決的小問題
  • 可擴展性與團隊效率 (Scalability and Team Efficiency): 支撐 APP 與團隊的成長,降低溝通與整合成本

主流 Flutter 架構巡禮

在做出選擇前,讓我們先快速瀏覽一下當今 Flutter 生態中幾個知名的架構模式。它們大多都源自於一個共同的基礎:三層式架構 (Three-Layer Architecture)。

  • 呈現層 (Presentation Layer):使用者所看到的 UI 介面與互動
  • 業務邏輯層 (Business Logic / Domain Layer):App 的核心商業規則與邏輯
  • 資料層 (Data Layer):負責資料的存取、儲存與網路請求

不同的架構模式,可以看作是對「這三層之間該如何溝通」的不同詮釋:

  • BLoC (Business Logic Component):UI 發送事件,Bloc 處理後透過 Stream 回傳狀態,資料流單向且可預測
  • MVVM (Model-View-ViewModel):ViewModel 為 UI 量身打造,將所有 UI 所需的資料和邏輯都準備好
  • Clean Architecture:以業務邏輯為中心,所有依賴都指向內部,實現完美的解耦合

架構選型的權衡分析

在決定採用 Clean Architecture 之前,讓我們先看看各種架構模式的優缺點:

考量因素 Clean Architecture BLoC Pattern MVVM 傳統 MVC
學習曲線 較陡峭 ⚠️ 中等 ○ 較平緩 ✓ 簡單 ✓
可測試性 極高 🎯 高 ✓ 中等 ○ 低 ✗
大型專案適用性 極佳 🎯 良好 ✓ 中等 ○ 差 ✗
團隊協作 極佳 🎯 良好 ✓ 一般 ○ 差 ✗
維護成本 中等 ○ 中等 ○ 中等 ○ 高 ✗
開發速度 初期慢,後期快 ○ 穩定 ○ 快 ✓ 初期快,後期慢 ○

我們的選擇:Clean Architecture (整潔架構)

在「Crew Up!」專案中,我們將採用 Clean Architecture 作為最高指導原則。這並非要取代 BLoC 或 MVVM,而是將它們納入一個更宏觀、更穩固的藍圖之中。

Clean Architecture 由 Robert C. Martin (Uncle Bob) 提出,其核心思想具有革命性:
軟體的中心應該是「領域 (Domain)」,也就是核心業務邏輯,而非資料庫或框架。

這個架構只有一條至關重要的黃金準則:

依賴原則 (The Dependency Rule):所有依賴關係,都必須指向「內部」。

等等,這不就是三層式架構嗎?一個決定性的區別

看到這裡,你心中可能會有個疑問:「呈現層、業務邏輯層、資料層... 這聽起來不就是傳統的『三層式架構』嗎?」

這是一個非常好的問題,答案是:它們看似相似,但在哲學上根本不同。

傳統的三層式架構是一種「線性」或「堆疊式」的結構:

UI 層 → 依賴 → 業務邏輯層 → 依賴 → 資料存取層

在這種結構下,依賴是單向穿透的。位於核心的「業務邏輯層」卻依賴於最底下的「資料存取層」。這意味著,如果你的資料庫換了、API 格式變了(資料層的細節),你的核心業務邏輯可能被迫需要修改。這就像是國家的法律,會因為邊境哨所的武器更新而需要重寫一樣,非常不合理。

而 Clean Architecture 是一種「放射狀」或「同心圓」的結構,其靈魂在於依賴反轉原則 (Dependency Inversion Principle)

Presentation 層 (UI) → 依賴 → Domain 層
Data 層 → 依賴 → Domain 層

看見關鍵了嗎?箭頭的方向完全不同。所有的依賴關係都指向中心的 Domain 層。Domain
層是立定規則的太陽,其他層都是圍繞它運行的行星,而不是一層疊一層的積木。

這個核心差異,正是 Clean Architecture 強大生命力的來源。

Clean Architecture 的三層結構

在我們的專案中,Clean Architecture 具體實踐為三個層次:

1. Domain Layer (領域層) - 系統的心臟

  • 包含所有核心業務規則
  • 完全獨立,不含任何 Flutter 或外部套件的程式碼
  • 定義 Repository 介面
  • 實作 UseCase(業務邏輯)

2. Data Layer (資料層) - 契約的實現者

  • 負責所有資料的來源與管理
  • 實作 Domain 層定義的 Repository 介面
  • 處理網路請求、本地儲存、資料轉換

3. Presentation Layer (呈現層) - UI 的管理者

  • 負責向使用者展示資訊
  • 使用 Riverpod 進行狀態管理
  • 呼叫 Domain 層的 UseCase

依賴反轉的實現

所有依賴關係都指向 Domain 層:

  • Presentation 層依賴 Domain 層的 UseCase
  • Data 層依賴 Domain 層的 Repository 介面
  • 透過依賴注入(Riverpod)管理這些依賴關係

為什麼選擇 Clean Architecture?

Crew Up! 作為一個社交應用,預期會有:

  • 複雜的業務邏輯(活動管理、用戶互動)
  • 多人協作開發需求
  • 長期維護與功能擴展

Clean Architecture 的優勢:

  • 最佳的可測試性: Domain 層純 Dart 程式碼,100% 可測試
  • 支援長期擴展: 依賴反轉讓我們能輕鬆替換實作
  • 團隊協作友好: 清晰的分層讓不同開發者能專注於不同層面
  • 與 SOLID 原則完美對齊: 符合現代軟體開發最佳實踐

何時不建議使用 Clean Architecture?

以下情況可能不適合:

  • 小型專案 (< 10 個畫面):可能造成過度工程化
  • 快速原型開發 (MVP):開發速度優先於架構完美性
  • 單人短期專案:複雜度可能大於收益
  • 團隊經驗不足:學習成本過高,影響交付時間

程式碼組織:功能優先 (Feature-first)

為了組織好上述的架構分層,我們將採用「功能優先 (Feature-first)」的資料夾結構。

前面討論的 Presentation, Domain, Data 三層,要如何對應到我們的資料夾結構中呢?答案就在每一個「功能」資料夾內部。這種以業務功能為核心來組織程式碼的方式,能大幅提高專案的內聚性、可讀性和長期可維護性。

特性 Feature-first (功能優先) Layer-first (層優先)
頂層組織 功能 (Features) 層 (Layers)
功能內聚性 (同一功能的所有程式碼都在一起) 低 (同一功能的程式碼分散在各層)
維護性 較容易 (修改功能時,影響範圍集中) 較困難 (修改時需跨多個資料夾)
團隊協作 優秀 (每個團隊成員可專注一個功能) 一般 (容易產生合併衝突)

動手時間:建立專案與目錄

現在就讓我們開始動手,建立專案與檔案結構!

  1. 建立專案

    flutter create crew_up
    
  2. 建立基本目錄結構
    lib/ 資料夾下建立以下「功能優先」的目錄結構:

    lib/
    ├── main.dart                    // 專案的進入點
    ├── app/                         // App 全域設定與配置
    │   ├── config/                  // 配置檔案
    │   └── core/                    // 核心基礎設施
    ├── common/                      // 跨功能模組的共用程式碼
    │   └── widgets/                // 可重用的 UI 元件
    └── features/                    // 以業務功能為核心的模組
        ├── activity/               // 「活動」功能模組
        │   ├── data/               // Data Layer
        │   ├── domain/             // Domain Layer  
        │   └── presentation/       // Presentation Layer
        ├── home/                   // 「首頁」功能模組
        └── notification/           // 「通知」功能模組
    

下一步預告:Design System 的建構

有了穩固的架構基礎,明天我們將開始建構 Crew Up! 的視覺語言系統。在 Day 2 - Design System 的哲學與實作中,我們將:

  • 從 Figma 設計稿轉換為 Flutter 程式碼
  • 建立完整的顏色系統、字型系統和間距系統
  • 實作第一個符合 Clean Architecture 的 UI 元件

結語

恭喜!我們完成了這個系列最重要的一天。

今天,我們沒有寫任何一行 App 功能程式碼,但我們完成了更關鍵的事:為「Crew Up!」這座未來的數位城市,制定了完整的都市計畫。我們劃分了商業區(Domain)、住宅區(Presentation)與交通幹道(Data),並確立了所有建設都必須遵守的核心法規(Dependency Rule)。

更重要的是,我們深入理解了:

  • 依賴反轉原則如何讓系統更具彈性和可測試性
  • Clean Architecture 與傳統三層架構的本質差異
  • 功能優先的程式碼組織如何提升團隊協作效率

有了這份完整的架構藍圖,往後的開發將會更有效率、更有條理,且能從容應對未來的需求變化和團隊擴展。

期待與您繼續這趟 Flutter 職人之路的探索!🚀


📋 相關資源

📝 專案資訊

  • 專案名稱: Crew Up!
  • 開發日誌: Day 1 - 專案啟動與架構選型
  • 文章日期: 2025-09-15
  • 技術棧: Flutter 3.8+, Dart 3.8+, Riverpod 2.6+, Clean Architecture

下一篇
Day 2 - 設計系統的哲學與實作
系列文
我的 Flutter 進化論:30 天打造「Crew Up!」的架構之旅11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言