如果你一路讀到這裡,iOS 架構系列的選項已經全部攤在眼前:MVC、MVVM、MVP、VIPER、Clean Architecture、MV,以及 TCA。
但最難的問題仍然存在。「所以我們的 App 該用哪一個?」
「沒有標準答案,只有取捨」雖然沒錯,但光靠這句話仍無法做決定。今天作為系列最後一篇,整理出能真正做決策的具體標準。
標準 1:團隊規模——架構是人的問題
首先,架構的重量應該配合人數,而不是程式碼量。
如果是1~2 人的團隊,速度比結構一致更重要。以 SwiftUI 來說,MV(Model–View)加上 Repository 就足夠;若使用 UIKit,從 MVC 分離畫面切換與網路功能也已足夠。在這種規模導入 VIPER(View、Interactor、Presenter、Entity、Router)或 TCA(The Composable Architecture),很容易讓維護結構的時間侵蝕功能開發時間。
從3~10 人的團隊開始,團隊需要對「邏輯放在哪裡」達成共識。MVVM + UseCase/Repository 是這個區間穩妥的標準。每個畫面的結構一致,才能降低程式碼審查與新人上手的成本。
如果是10 人以上、分成多個 squad,一致性與模組邊界最優先。這時可以依功能模組化並加上 Clean Architecture 分層;若狀態複雜度高,也可選擇以 TCA 作為標準。VIPER 與 RIBs 曾被實際採用,也正是這類規模的組織。
標準 2:App 壽命——壽命越長,越值得投資邊界
為壽命短的 App(原型、驗證用 MVP(Minimum Viable Product)、活動 App)建立分層是浪費。因為目標就是快速製作、快速學習。
若是預計維持 3 年以上的產品,情況就不同了。期間伺服器 API 會改版、設計會重做,也可能經歷 UIKit→SwiftUI 等框架轉換。真正有價值的不是華麗的模式,而是邊界,例如隱藏資料來源的 Repository,以及承載商業規則的 UseCase。有邊界就能局部替換,沒有就只能全面重寫。
標準 3:狀態複雜度——唯一能合理化 TCA 的軸
如果 App 大多只是「從伺服器取得資料、顯示出來,再將輸入送回伺服器」,MVVM/MV 就足夠。相反地,如果多個畫面同時編輯同一份狀態,或牽涉即時同步、離線合併與複雜 undo,TCA 強制控管狀態變更路徑的成本才開始合理。
如前一篇所整理,TCA 不是錯誤的選擇,而是昂貴的選擇。若這個軸向的複雜度不高,就無法回收那筆成本。
一頁總結
| 情境 | 建議 |
|---|---|
| 個人・原型 | MV(SwiftUI)或 MVC + 最小限度分離 |
| 小型團隊・一般服務 App | MVVM + Repository(必要時加入 UseCase) |
| 舊版 UIKit・導入繫結的負擔高 | MVP + Coordinator |
| 大型組織・長壽命產品 | Clean Architecture 分層 + 依功能模組化 |
| 狀態複雜度高的領域 | TCA(前提是團隊投入學習) |
比表格更重要的是:**無論從哪一格開始,之後都能移到旁邊的格子。**但要能移動,還有一個條件。
無論選擇哪種架構,都必須遵守的不變式
貫穿整個系列的原則,可以濃縮成一句話:
不要讓 View 直接接觸網路與資料庫,並將商業規則放在畫面程式碼之外。
只要遵守這個不變式,從 MVC 移到 MVVM、再從 MVVM 移到 TCA,就能縮小成「替換畫面層」的問題。反之,若這點崩潰,導入任何流行架構都會變成全面重寫。架構名稱會留在履歷上,但真正拯救產品的是邊界。
最後,架構轉換的正確做法不是大爆炸式重寫,而是從新畫面開始逐步進行。因為流行就重做運作正常的既有畫面,最後大多只會後悔。
系列完結
把八篇文章各濃縮成一句話,就是這樣。
- MVC:理解責任集中在 UIViewController 的結構,是起點
- MVVM:抽離畫面狀態並以繫結同步;沒有繫結就只完成一半
- MVP vs MVVM:差別在於中介物件是否知道 View
- VIPER:分離的極致,其遺產由 Coordinator 與 UseCase 延續
- Clean Architecture:相依性只能向內,從 Repository 開始
- TCA:控制狀態變更路徑,在複雜度足以合理化成本時採用
- MV 爭論:本質不在名稱,而在邏輯的位置與相依性方向
- 選擇指南:依團隊規模、App 壽命與狀態複雜度選擇,遵守不變式並逐步轉換
架構不是目的地,而是工具。投資於邊界,讓團隊與 App 成長後仍能切換架構。

![[iOS 架構 #8] iOS 架構選擇指南:依團隊規模、App 壽命與狀態複雜度選擇 封面圖](/assets/images/posts/3dfe56b5-14ec-4e0a-846d-2d128e15798e/1.jpg)