导入
架构原则与分层设计
了解移动应用中分层设计的基础知识,并学习架构原则。
移动应用架构模式
架构原则与分层设计
移动应用架构模式
单向数据流
依赖注入与模块化设计
面向前端的后端(BFF)在移动端的应用
导航与页面流程架构
一个明确的架构能够确保我们的应用:
-
在功能扩展和演进过程中仍保持易于维护。
-
通过职责隔离支持可测试性。
-
通过高效的分层设计处理性能瓶颈。
-
提供更清晰的数据流,避免面条代码,并消除逻辑位置的模糊性。
一个明确的架构能够确保我们的应用:
-
在功能扩展和演进过程中仍保持易于维护。
-
通过职责隔离支持可测试性。
-
通过高效的分层设计处理性能瓶颈。
-
提供更清晰的数据流,避免面条代码,并消除逻辑位置的模糊性。
1// 在屏幕 A 中 2if (email.contains("@") && email.length > 5) {...} 3// 在屏幕 B 中 4if (email.contains("@") && email.length > 5) {...}
1fun isValidEmail(email: String): Boolean = ...
...
移动系统中的关注点分离
表格
| 原则 | 指导思想 | 简化的移动端示例 |
|---|---|---|
| 单一职责 | 每个类或组件只负责一项具体任务 | 一个保存用户设置的类不应同时更新界面或发送日志 |
| 开闭原则 | 系统支持新增行为而不修改现有代码 | 可以添加一种新的通知类型,而无需修改现有的告警逻辑 |
| 里氏替换 | 子类对象应能替换其父类对象而不破坏程序的正确性 | 从离线数据源切换到在线数据源不应破坏应用的工作方式 |
| 接口隔离 | 组件只被要求完成其需要的任务 | 设置界面仅请求用户偏好,不涉及无关的账户信息 |
| 依赖倒置 | 高层逻辑依赖于通用规则,而非具体细节 | 只要遵循定义的接口,一个功能可与任意图像加载器配合工作 |
1userViewModel.userState.observe(viewLifecycleOwner) { state -> 2 when (state) { 3 is Success -> showUser(state.data) 4 is Error -> showError() 5 is Loading -> showLoading() 6 } 7}
1class FetchUserUseCase(private val userRepository: UserRepository) { 2 suspend fun execute(userId: String): User { 3 return userRepository.getUserById(userId) 4 } 5}
1class UserRepositoryImpl( 2 private val apiService: ApiService, 3 private val userDao: UserDao 4) : UserRepository { 5 6 override suspend fun getUserById(id: String): User { 7 val response = apiService.fetchUser(id) 8 return response.toDomainModel() 9 } 10}
...
分层架构概览
1// 在登录界面中 2let response = apiClient.login(email, password) 3if response.status == "OK" { 4 userDefaults.set(response.token, forKey: "token") 5 showHomeScreen() 6}
UI 层
1loginService.login(email, password) { success in 2 if success { 3 showHomeScreen() 4 } else { 5 showError() 6 } 7}
领域层
1class LoginService { 2 let authRepository: AuthRepository 3 4 init(authRepository: AuthRepository) { 5 self.authRepository = authRepository 6 } 7 8 func login(_ email: String, _ password: String, completion: @escaping (Bool) -> Void) { 9 authRepository.login(email, password) { token in 10 if let token = token { 11 authRepository.saveToken(token) 12 completion(true) 13 } else { 14 completion(false) 15 } 16 } 17 } 18}
数据层
1class AuthRepository { 2 func login(_ email: String, _ password: String, completion: @escaping (String?) -> Void) { 3 let response = apiClient.login(email, password) 4 completion(response.status == "OK" ? response.token : nil) 5 } 6 7 func saveToken(_ token: String) { 8 UserDefaults.standard.set(token, forKey: "token") 9 } 10}
表格
| 技术 | 目的 |
|---|---|
| 使用分层检查清单进行代码审查 | 确保逻辑出现在正确的层级 |
| 边界处使用接口 | 防止 UI 与数据基础设施之间的直接耦合 |
| 命名规范 | 让职责一目了然 |
| 按层级划分项目结构 | 物理上分离 UI、领域和数据逻辑 |
| 每层编写单元测试 | 在不依赖其他层的情况下验证逻辑 |
Coming soon to support pageflux-note