Skip to content

07 架构对比

目录

  1. 架构演进历史
  2. MVC 架构详解
  3. MVP 架构详解
  4. MVVM 架构详解
  5. MVI 架构详解
  6. VIPER 架构详解
  7. Clean Architecture
  8. 架构横向对比
  9. 架构选择指南
  10. 大厂架构实践
  11. 架构演进路线
  12. 面试考点

1. 架构演进历史

1.1 Android 架构发展时间线

2008 年 ──┬── Android 发布,没有官方架构推荐

2012 年 ──┼── MVC 成为事实标准

2014 年 ──┼── MVP 开始流行 (Google I/O)

2015 年 ──┼── MVVM 正式发布 (ViewBinding, DataBinding)

2017 年 ──┼── Jetpack 发布,推荐 MVVM + Repository

2019 年 ──┼── Jetpack Compose 发布,MVI 开始流行

2021 年 ──┼── Clean Architecture 广泛采用

2023 年 ──┴── Multi-module + Clean Architecture + Compose

1.2 为什么需要架构演进?

每个架构都是为了解决前一代的问题:

架构解决的问题引入的新问题
MVC没有架构,代码混乱UI 与逻辑耦合严重
MVPUI 与逻辑耦合接口过多,实现复杂
MVVM接口过多双向数据绑定性能问题
MVI状态管理混乱学习成本高
Clean关注点不分离代码量增加

2. MVC 架构详解

2.1 MVC 架构原理

┌─────┐     ┌─────┐     ┌─────┐
│Model│────▶│Controller│────▶│View│
└─────┘     └─────┘     └─────┘
    ▲           │           │
    │           └───────────┘
    │               │
    └───────────────┘
  • Model: 数据和业务逻辑
  • View: UI 展示
  • Controller: 处理用户输入,更新 Model 和 View

2.2 MVC 在 Android 中的实现

kotlin
// Activity 扮演 Controller + View 的双重角色
class UserActivity : AppCompatActivity() {
    
    // View 部分
    private lateinit var userName: TextView
    private lateinit var userEmail: TextView
    private lateinit var refreshButton: Button
    
    // Controller 部分
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)
        
        initializeViews()
        setupListeners()
        loadData()
    }
    
    // Model 部分(通常直接调用 API)
    private fun loadData() {
        apiService.getUser { user ->
            runOnUiThread {
                userName.text = user.name
                userEmail.text = user.email
            }
        }
    }
    
    private fun setupListeners() {
        refreshButton.setOnClickListener {
            loadData() // 重复的加载逻辑
        }
    }
}

2.3 MVC 的问题

MVC 在 Android 中的问题:
├── Activity 过于臃肿 (1000+ 行代码) ❌
├── 业务逻辑分散在各个 Activity ❌
├── 难以测试 ❌
├── 代码复用困难 ❌
├── 生命周期管理混乱 ❌
└── UI 状态难以管理 ❌

2.4 MVC 适用场景

  • 小型 Demo 项目
  • 快速原型开发
  • 简单的工具类应用
  • 单个 Activity 的应用

3. MVP 架构详解

3.1 MVP 架构原理

┌─────┐
│View │──────┐
└─────┘      │

┌─────┐     ┌─────┐
│Model│────▶│Presenter│
└─────┘     └─────┘

              └────────┐

                 更新 View 状态
  • View: 只负责 UI 展示,通过接口与 Presenter 交互
  • Presenter: 处理业务逻辑,协调 View 和 Model
  • Model: 数据层

3.2 MVP 在 Android 中的实现

kotlin
// 1. View 接口
interface UserView {
    fun showLoading()
    fun hideLoading()
    fun showUser(user: User)
    fun showError(message: String)
}

// 2. Presenter
class UserPresenter(
    private val view: UserView,
    private val repository: UserRepository
) {
    fun getUser(userId: String) {
        view.showLoading()
        
        repository.getUser(userId) { result ->
            when (result) {
                is Result.Success -> {
                    view.hideLoading()
                    view.showUser(result.data)
                }
                is Result.Failure -> {
                    view.hideLoading()
                    view.showError(result.exception.message)
                }
            }
        }
    }
    
    fun onDestroy() {
        // 处理内存泄漏
    }
}

// 3. Activity 实现 View 接口
class UserActivity : AppCompatActivity(), UserView {
    
    private lateinit var presenter: UserPresenter
    private lateinit var userName: TextView
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)
        
        presenter = UserPresenter(this, userRepository)
        presenter.getUser("user123")
    }
    
    // View 接口实现
    override fun showLoading() {
        progressBar.visibility = View.VISIBLE
    }
    
    override fun hideLoading() {
        progressBar.visibility = View.GONE
    }
    
    override fun showUser(user: User) {
        userName.text = user.name
    }
    
    override fun showError(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
    
    override fun onDestroy() {
        super.onDestroy()
        presenter.onDestroy() // 手动管理生命周期
    }
}

3.3 MVP 的优点

  • ✅ 分离了 UI 和业务逻辑
  • ✅ Activity 不再臃肿
  • ✅ 易于单元测试
  • ✅ 代码复用性提高

3.4 MVP 的缺点

MVP 的缺点:
├── 接口过多,每个 View 需要一个接口 ❌
├── Presenter 数量爆炸 ❌
├── 需要手动管理生命周期 ❌
├── 不支持响应式编程 ❌
├── 配置复杂,样板代码多 ❌
└── 切换 View 时Presenter需要重新创建 ❌

3.5 MVP 适用场景

  • 中等规模项目
  • 需要一定测试覆盖
  • 团队熟悉接口编程
  • 不追求最新的架构模式

4. MVVM 架构详解

4.1 MVVM 架构原理

┌───────┐         ┌───────┐
│  View │◀───────▶│ViewModel│
└───────┘   数据绑定    └───────┘


                    ┌───────────┐
                    │Repository │
                    └───────────┘
  • View: UI 层,通过数据绑定与 ViewModel 连接
  • ViewModel: 管理 UI 状态,处理业务逻辑
  • Model/Repository: 数据层

4.2 MVVM 在 Android 中的实现

kotlin
// 1. ViewModel
class UserViewModel @Inject constructor(
    private val repository: UserRepository
) : ViewModel() {
    
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    
    private val _loading = MutableLiveData<Boolean>()
    val loading: LiveData<Boolean> = _loading
    
    private val _error = MutableLiveData<String>()
    val error: LiveData<String> = _error
    
    fun getUser(userId: String) {
        _loading.value = true
        
        viewModelScope.launch {
            try {
                val user = repository.getUser(userId)
                _user.value = user
                _loading.value = false
            } catch (e: Exception) {
                _error.value = e.message
                _loading.value = false
            }
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        // ViewModel 自动管理生命周期
    }
}

// 2. Activity/Fragment
class UserActivity : AppCompatActivity() {
    
    private lateinit var viewModel: UserViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)
        
        viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
        
        // 观察 ViewModel 状态
        viewModel.user.observe(this) { user ->
            userName.text = user.name
        }
        
        viewModel.loading.observe(this) { isLoading ->
            progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
        }
        
        viewModel.error.observe(this) { error ->
            Toast.makeText(this, error, Toast.LENGTH_SHORT).show()
        }
        
        // 加载数据
        viewModel.getUser("user123")
    }
}

4.3 MVVM 的优点

MVVM 的优点:
├── 自动管理生命周期 ✅
├── 支持配置变更(如旋转屏幕)✅
├── 数据绑定简化了 UI 更新 ✅
├── 易于测试 ✅
├── 支持响应式编程 ✅
├── Google 官方推荐 ✅
└── 生态完善(Jetpack)✅

4.4 MVVM 的缺点

MVVM 的缺点:
├── 双向数据绑定可能导致性能问题 ❌
├── 状态管理不够明确 ❌
├── 复杂的业务逻辑可能导致 ViewModel 臃肿 ❌
└── 学习 DataBinding/LiveData 需要时间 ❌

4.5 MVVM 适用场景

  • 大多数 Android 项目
  • 需要处理复杂 UI 状态
  • 团队希望使用官方推荐方案
  • 需要良好的配置变更支持

5. MVI 架构详解

5.1 MVI 架构原理

┌───────┐         ┌───────┐         ┌───────┐
│  View │───────▶│ViewModel│──────▶│ Reduce│
└───────┘  Event  └───────┘ Action  └───────┘
    ▲                                                │
    │                                                ▼
    └────────────────────────── StateFlow ←──────────┘
  • Model: 不可变的 State
  • View: 纯函数,State 的展示
  • ViewModel: 处理 Event,返回 Action,更新 State

5.2 MVI 在 Android 中的实现

kotlin
// 1. 定义 State (不可变)
@JvmInline
value class UserScreenState(
    val user: User? = null,
    val isLoading: Boolean = false,
    val error: String? = null
) {
    companion object {
        val Initial = UserScreenState()
    }
}

// 2. 定义 Event
sealed class UserScreenEvent {
    object LoadUser : UserScreenEvent()
    object RefreshUser : UserScreenEvent()
    data class UpdateName(val name: String) : UserScreenEvent()
}

// 3. ViewModel (处理 Event,返回 State Flow)
class UserViewModel @Inject constructor(
    private val repository: UserRepository
) : ViewModel() {
    
    private val _event = MutableSharedFlow<UserScreenEvent>()
    val event: SharedFlow<UserScreenEvent> = _event.asSharedFlow()
    
    val state: StateFlow<UserScreenState> = buildStateFlow()
    
    private fun buildStateFlow(): StateFlow<UserScreenState> {
        return _event
            .stateIn(
                viewModelScope,
                SharingStarted.WhileSubscribed(5000),
                UserScreenState.Initial
            )
            .scan(UserScreenState.Initial) { state, event ->
                when (event) {
                    is UserScreenEvent.LoadUser -> {
                        state.copy(isLoading = true)
                    }
                    is UserScreenEvent.RefreshUser -> {
                        // 触发刷新
                        state
                    }
                    else -> state
                }
            }
    }
    
    fun onEvent(event: UserScreenEvent) {
        viewModelScope.launch {
            _event.emit(event)
        }
    }
    
    private fun loadUser() {
        viewModelScope.launch {
            try {
                val user = repository.getUser("user123")
                _state.update { it.copy(user = user, isLoading = false) }
            } catch (e: Exception) {
                _state.update { it.copy(error = e.message, isLoading = false) }
            }
        }
    }
}

// 4. Compose UI (纯函数)
@Composable
fun UserScreen(
    state: UserScreenState,
    onEvent: (UserScreenEvent) -> Unit
) {
    when {
        state.isLoading -> {
            CircularProgressIndicator()
        }
        state.error != null -> {
            ErrorView(message = state.error)
            Button(onClick = { onEvent(UserScreenEvent.LoadUser) }) {
                Text("Retry")
            }
        }
        state.user != null -> {
            UserDetail(user = state.user!!)
        }
    }
}

5.3 MVI 的优点

MVI 的优点:
├── 单一数据源 (Single Source of Truth) ✅
├── 状态完全可预测 ✅
├── 易于调试和测试 ✅
├── 支持时间旅行调试 ✅
├── 与 Compose 完美配合 ✅
└── 状态变化可追溯 ✅

5.4 MVI 的缺点

MVI 的缺点:
├── 学习曲线陡峭 ❌
├── 需要理解函数式编程 ❌
├── 代码量可能增加 ❌
├── 性能优化复杂 ❌
└── 不适合简单场景 ❌

5.5 MVI 适用场景

  • 使用 Jetpack Compose 的项目
  • 复杂的状态管理需求
  • 团队有函数式编程经验
  • 对调试和测试有较高要求

6. VIPER 架构详解

6.1 VIPER 架构原理

┌───────┐
│ View  │──────┐
└───────┘      │

┌───────┐     ┌───────┐
│Interactor│◀──│Presenter│
└───────┘     └───────┘
    │               │
    ▼               │
┌───────┐           │
│Entity │───────────┘
└───────┘


┌───────┐
│Repository│
└───────┘
  • View: UI 展示
  • Interceptor: 用户入口
  • Presenter: 协调各个组件
  • Interactor: 业务逻辑
  • Entity: 领域实体
  • Repository: 数据访问

6.2 VIPER 在 Android 中的实现

kotlin
// 1. Entity
data class UserEntity(
    val id: String,
    val name: String,
    val email: String
)

// 2. Repository Interface
interface UserRepository {
    suspend fun getUser(userId: String): UserEntity
}

// 3. Interactor
class GetUserInteractor(
    private val repository: UserRepository
) {
    suspend fun execute(userId: String): Either<Exception, UserEntity> {
        return try {
            val user = repository.getUser(userId)
            Right(user)
        } catch (e: Exception) {
            Left(e)
        }
    }
}

// 4. Presenter
class UserPresenter(
    private val interactor: GetUserInteractor,
    private val view: UserView
) {
    fun loadUser(userId: String) {
        view.showLoading()
        
        viewModelScope.launch {
            when (val result = interactor.execute(userId)) {
                is Right -> {
                    view.hideLoading()
                    view.showUser(result.value)
                }
                is Left -> {
                    view.hideLoading()
                    view.showError(result.value.message)
                }
            }
        }
    }
}

// 5. View Interface
interface UserView {
    fun showLoading()
    fun hideLoading()
    fun showUser(user: UserEntity)
    fun showError(message: String)
}

// 6. Activity (View + Interactor)
class UserActivity : AppCompatActivity(), UserView {
    
    private lateinit var presenter: UserPresenter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val interactor = GetUserInteractor(userRepository)
        presenter = UserPresenter(interactor, this)
        
        presenter.loadUser("user123")
    }
    
    // View 接口实现
    override fun showLoading() { /* ... */ }
    override fun hideLoading() { /* ... */ }
    override fun showUser(user: UserEntity) { /* ... */ }
    override fun showError(message: String) { /* ... */ }
}

6.3 VIPER 的优点

VIPER 的优点:
├── 职责分离非常明确 ✅
├── 每个组件都有单一职责 ✅
├── 易于测试 ✅
├── 代码组织清晰 ✅
└── 适合大型项目 ✅

6.4 VIPER 的缺点

VIPER 的缺点:
├── 组件数量多,代码量大 ❌
├── 学习曲线非常陡峭 ❌
├── 对于简单功能过度设计 ❌
├── 文件数量爆炸 ❌
└── 团队协作成本高 ❌

6.5 VIPER 适用场景

  • 超大型项目
  • 长期维护的项目
  • 团队有架构设计经验
  • 对代码质量要求极高

7. Clean Architecture

7.1 Clean Architecture 原理

┌─────────────────────────────────────┐
│         Presentation Layer          │
│   (Activity, Fragment, ViewModel)   │
├─────────────────────────────────────┤
│           Domain Layer              │
│   (Entity, UseCase, Repository API) │
├─────────────────────────────────────┤
│            Data Layer               │
│  (Repository Impl, DataSource)      │
└─────────────────────────────────────┘

7.2 Clean Architecture 的特点

  • 以业务逻辑为中心
  • 依赖倒置原则
  • 框架独立
  • 数据库独立
  • UI 独立

7.3 Clean Architecture 与其他架构的关系

Clean Architecture 是一个框架,可以包含:
├── MVVM (Presentation 层)
├── Repository 模式 (Data 层)
├── Use Case (Domain 层)
└── 依赖注入 (跨层)

8. 架构横向对比

8.1 综合对比表

特性MVCMVPMVVMMVIVIPERClean
职责分离⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
可测试性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
学习曲线⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
代码量⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
灵活性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
生态支持⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
官方推荐⚠️⚠️

8.2 代码对比

kotlin
// MVC - 所有逻辑在一个类
class UserActivity : AppCompatActivity() {
    fun loadData() { /* API 调用 + UI 更新 */ }
}

// MVP - 分离 View 和 Presenter
interface UserView { /* View 接口 */ }
class UserPresenter(view: UserView) { /* 业务逻辑 */ }
class UserActivity : AppCompatActivity(), UserView { /* UI 实现 */ }

// MVVM - ViewModel 管理状态
class UserViewModel : ViewModel() {
    val user = MutableLiveData<User>()
}
class UserActivity : AppCompatActivity() {
    val viewModel: UserViewModel by viewModel()
}

// MVI - 不可变状态流
data class UserState(val user: User? = null)
class UserViewModel {
    val state = StateFlow<UserState>(UserState())
}

// VIPER - 多个组件协作
class UserView
class UserPresenter
class UserInteractor
class UserRepository
class UserEntity

// Clean Architecture - 三层分离
class UserViewModel // Presentation
class GetUserUseCase // Domain
class UserRepositoryImpl // Data

8.3 性能对比

架构启动速度内存占用流畅度
MVC⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
MVP⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
MVVM⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
MVI⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
VIPER⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Clean⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

9. 架构选择指南

9.1 选择因素

选择架构时考虑:
├── 项目规模
├── 团队规模
├── 团队经验
├── 项目周期
├── 维护周期
├── 测试要求
├── 性能要求
└── 技术栈

9.2 项目规模 vs 架构选择

项目规模推荐架构理由
Demo/原型MVC快速开发,不需要复杂架构
小型项目 (❤️ 个月)MVP / MVVM平衡开发效率和可维护性
中型项目 (3-12 个月)MVVM + Repository官方推荐,生态完善
大型项目 (>12 个月)MVVM + Clean清晰的分层,易于维护
超大型项目VIPER / Clean职责分离,易于扩展

9.3 团队经验 vs 架构选择

团队经验推荐架构理由
初级团队MVC / MVP学习曲线平缓
中级团队MVVM平衡复杂度和可维护性
高级团队MVI / Clean充分利用架构优势
专家级团队VIPER / Custom定制最佳架构

9.4 技术栈 vs 架构选择

技术栈推荐架构理由
View + RetrofitMVP / MVVM成熟的方案
ComposeMVI / MVVM函数式编程友好
Kotlin CoroutinesMVVM / MVI异步处理友好
HiltMVVM / Clean依赖注入支持

10. 大厂架构实践

10.1 字节跳动

字节架构特点:
├── 模块化架构
├── MVVM + Clean Architecture
├── 自研框架 (Flutter 混合)
├── 组件化 + 插件化
└── 强类型 + 静态检查

10.2 美团

美团架构特点:
├── 领域驱动设计 (DDD)
├── Clean Architecture
├── 多模块划分
├── 基础组件库
└── 数据埋点体系

10.3 阿里巴巴

阿里架构特点:
├── 端云一体化
├── React Native / Flutter
├── 组件化架构
├── 业务中台化
└── 智能化 (AI 集成)

10.4 腾讯

腾讯架构特点:
├── 自研框架 (TXIM, TXVideo)
├── 微前端架构
├── 混合开发 (Native + H5)
├── 性能优化极致
└── 游戏化体验

10.5 大厂架构趋势

2024 年大厂架构趋势:
├── Jetpack Compose 全面采用 ✅
├── Multi-module 项目结构 ✅
├── Clean Architecture 主流 ✅
├── Kotlin 多平台 (KMP) ✅
├── 性能监控自动化 ✅
├── 测试覆盖率要求提高 ✅
└── AI 辅助开发 ✅

11. 架构演进路线

11.1 个人技术成长路线

Level 1 (初级):
└── MVC -> 理解基本概念

Level 2 (中级):
└── MVP / MVVM -> 掌握分层思想

Level 3 (高级):
└── MVVM + Repository -> 掌握数据流

Level 4 (专家):
└── Clean Architecture -> 掌握架构设计

Level 5 (架构师):
└── 自定义架构 -> 根据场景定制

11.2 项目架构演进路线

Phase 1 (MVP):
Activity + API 调用

Phase 2 (分离):
Activity + Manager

Phase 3 (MVP):
View + Presenter + Model

Phase 4 (MVVM):
View + ViewModel + Repository

Phase 5 (Clean):
Presentation + Domain + Data

Phase 6 (模块化):
Multi-module + Feature 模块

11.3 演进注意事项

架构演进注意事项:
├── 不要过度设计
├── 渐进式重构
├── 保持向后兼容
├── 测试先行
├── 团队共识
├── 文档同步
└── 性能监控

12. 面试考点

12.1 基础概念题

Q1: 说说你了解的 Android 架构有哪些?

参考答案:

常见的 Android 架构:
1. MVC - Model-View-Controller
2. MVP - Model-View-Presenter
3. MVVM - Model-View-ViewModel
4. MVI - Model-View-Intent
5. VIPER - View-Interactor-Presenter-Entity-Repository
6. Clean Architecture

我主要使用 MVVM + Repository + Clean Architecture 的组合。

Q2: MVVM 和 MVP 有什么区别?

参考答案:

主要区别:
1. 数据流: MVP 是单向,MVVM 是双向数据绑定
2. 生命周期: MVP 手动管理,MVVM 自动管理
3. 配置变更: MVP 需要处理,MVVM 自动处理
4. 测试: 都易于测试,但 MVVM 更简单
5. 学习曲线: MVP 平缓,MVVM 稍陡

12.2 架构设计题

Q3: 如何设计一个支持离线功能的消息列表?

参考答案:

架构选择:MVVM + Repository + Clean

Domain 层:
- Message Entity
- GetMessageUseCase
- MessageRepository Interface

Data 层:
- MessageRepositoryImpl (缓存优先策略)
- LocalDataSource (Room)
- RemoteDataSource (Retrofit)
- Mapper

Presentation 层:
- MessageViewModel
- MessageListScreen

离线策略:
1. 优先显示本地数据
2. 后台同步服务器
3. 冲突解决策略
4. 离线消息队列

Q4: 如何选择项目的架构?

参考答案:

考虑因素:
1. 项目规模
2. 团队经验
3. 维护周期
4. 性能要求
5. 技术栈

我的选择标准:
- 小项目:MVVM
- 中项目:MVVM + Repository
- 大项目:Clean Architecture
- Compose 项目:MVI

12.3 实战问题

Q5: 你在项目中遇到过哪些架构问题?如何解决的?

参考答案模板:

问题:Activity 代码过多,难以维护
解决:提取 ViewModel,采用 MVVM 架构

问题:状态管理混乱
解决:引入 StateFlow,采用 MVI 模式

问题:数据源管理复杂
解决:引入 Repository 模式

问题:模块耦合严重
解决:采用 Clean Architecture 分层

Q6: Clean Architecture 的优缺点是什么?

参考答案:

优点:
- 职责分离清晰
- 易于测试
- 技术替换方便
- 长期维护友好

缺点:
- 代码量增加
- 学习曲线陡峭
- 小项目可能过度设计
- 初期开发速度较慢

适用场景:
- 长期维护的项目
- 大型项目
- 团队有架构经验

总结

选择架构不是选择"最好的",而是选择"最适合的"。

架构选择原则:

  1. 简单优先:能简单就不要复杂
  2. 团队优先:选择团队熟悉的
  3. 渐进演进:不要一次性重构
  4. 测试驱动:架构应该易于测试
  5. 性能考虑:架构不影响性能

学习建议:

  1. 从 MVC 开始理解基本概念
  2. 掌握 MVP 理解分层思想
  3. 深入学习 MVVM + Repository
  4. 了解 Clean Architecture 和 MVI
  5. 根据项目需求选择合适的架构

架构是手段,不是目的。最终目标是写出可维护、可测试、可扩展的代码。