Files
mkdocs/docs/Google开发文档体系/最佳实践/应用架构最佳实践.md
2026-01-16 14:54:07 +08:00

18 KiB
Raw Blame History

应用架构最佳实践

良好的应用架构是Android应用开发的基础它直接影响应用的可维护性、可测试性和可扩展性。本文档介绍Android应用架构设计的最佳实践。

目录


架构设计原则

1. 关注点分离Separation of Concerns

单一职责原则

// ✅ 好的设计:每个类只有一个职责
class UserRepository {
    fun getUser(userId: String): User {
        // 只负责数据获取
    }
}

class UserViewModel : ViewModel() {
    private val repository: UserRepository
    
    fun loadUser(userId: String) {
        // 只负责UI逻辑
        viewModelScope.launch {
            val user = repository.getUser(userId)
            _user.value = user
        }
    }
}

// ❌ 不好的设计:一个类承担多个职责
class UserManager {
    fun getUser(userId: String): User { }
    fun saveUser(user: User) { }
    fun displayUser(user: User) { } // UI逻辑不应该在这里
    fun validateUser(user: User) { } // 业务逻辑不应该在这里
}

2. 依赖倒置原则Dependency Inversion

依赖接口而非实现

// ✅ 好的设计:依赖接口
interface UserRepository {
    suspend fun getUser(userId: String): User
}

class UserRepositoryImpl(
    private val apiService: ApiService,
    private val localDataSource: UserLocalDataSource
) : UserRepository {
    override suspend fun getUser(userId: String): User {
        // 实现细节
    }
}

class UserViewModel(
    private val repository: UserRepository // 依赖接口
) : ViewModel() {
    // ...
}

// ❌ 不好的设计:依赖具体实现
class UserViewModel(
    private val repository: UserRepositoryImpl // 依赖具体实现
) : ViewModel()

3. 开闭原则Open/Closed Principle

对扩展开放,对修改关闭

// ✅ 好的设计:通过扩展添加功能
abstract class DataSource {
    abstract suspend fun getData(): Data
}

class RemoteDataSource : DataSource() {
    override suspend fun getData(): Data {
        // 从远程获取数据
    }
}

class LocalDataSource : DataSource() {
    override suspend fun getData(): Data {
        // 从本地获取数据
    }
}

// 可以添加新的数据源而不修改现有代码
class CacheDataSource : DataSource() {
    override suspend fun getData(): Data {
        // 从缓存获取数据
    }
}

4. 接口隔离原则Interface Segregation

使用小而专的接口

// ✅ 好的设计:小而专的接口
interface Readable {
    fun read(): String
}

interface Writable {
    fun write(data: String)
}

class FileManager : Readable, Writable {
    override fun read(): String { }
    override fun write(data: String) { }
}

// ❌ 不好的设计:大而全的接口
interface DataManager {
    fun read(): String
    fun write(data: String)
    fun delete()
    fun update()
    fun search()
    // 太多方法,违反接口隔离原则
}

分层架构

1. 三层架构

表现层Presentation Layer

// UI层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)[UserViewModel::class.java]
        
        viewModel.user.observe(this) { user ->
            // 更新UI
            updateUI(user)
        }
        
        viewModel.loadUser(userId)
    }
}

// ViewModel处理UI逻辑
class UserViewModel(
    private val getUserUseCase: GetUserUseCase
) : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    
    fun loadUser(userId: String) {
        viewModelScope.launch {
            try {
                val user = getUserUseCase(userId)
                _user.value = user
            } catch (e: Exception) {
                // 处理错误
            }
        }
    }
}

领域层Domain Layer

// UseCase业务逻辑
class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(userId: String): Result<User> {
        return try {
            val user = repository.getUser(userId)
            Result.success(user)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}

// Entity领域实体
data class User(
    val id: String,
    val name: String,
    val email: String
)

// Repository接口定义数据访问接口
interface UserRepository {
    suspend fun getUser(userId: String): User
}

数据层Data Layer

// Repository实现
class UserRepositoryImpl(
    private val remoteDataSource: UserRemoteDataSource,
    private val localDataSource: UserLocalDataSource
) : UserRepository {
    override suspend fun getUser(userId: String): User {
        return try {
            // 先尝试从远程获取
            val user = remoteDataSource.getUser(userId)
            // 保存到本地
            localDataSource.saveUser(user)
            user
        } catch (e: Exception) {
            // 如果远程失败,从本地获取
            localDataSource.getUser(userId)
        }
    }
}

// 远程数据源
class UserRemoteDataSource(
    private val apiService: ApiService
) {
    suspend fun getUser(userId: String): User {
        return apiService.getUser(userId).toDomain()
    }
}

// 本地数据源
class UserLocalDataSource(
    private val userDao: UserDao
) {
    suspend fun getUser(userId: String): User {
        return userDao.getUser(userId).toDomain()
    }
    
    suspend fun saveUser(user: User) {
        userDao.insertUser(user.toEntity())
    }
}

2. Clean Architecture

依赖规则

表现层 → 领域层 ← 数据层
// 领域层不依赖任何其他层
// Domain Layer
interface UserRepository {
    suspend fun getUser(userId: String): User
}

class GetUserUseCase(
    private val repository: UserRepository // 依赖接口
) {
    suspend operator fun invoke(userId: String): User {
        return repository.getUser(userId)
    }
}

// 数据层实现领域层的接口
// Data Layer
class UserRepositoryImpl : UserRepository {
    override suspend fun getUser(userId: String): User {
        // 实现
    }
}

// 表现层依赖领域层
// Presentation Layer
class UserViewModel(
    private val getUserUseCase: GetUserUseCase // 依赖UseCase
) : ViewModel()

模块化设计

1. 功能模块化

模块结构

app/
├── app/                    # 主模块
├── core/                   # 核心模块(通用功能)
│   ├── core-common/
│   ├── core-network/
│   └── core-database/
├── feature/                # 功能模块
│   ├── feature-home/
│   ├── feature-user/
│   └── feature-settings/
└── buildSrc/               # 构建脚本

模块依赖关系

// app/build.gradle
dependencies {
    implementation project(':core:core-common')
    implementation project(':core:core-network')
    implementation project(':feature:feature-home')
    implementation project(':feature:feature-user')
}

// feature-home/build.gradle
dependencies {
    implementation project(':core:core-common')
    // feature模块不依赖其他feature模块
}

2. 组件化架构

组件通信

// 使用接口定义组件通信
interface HomeNavigation {
    fun navigateToUserDetail(userId: String)
    fun navigateToSettings()
}

// Home模块实现
class HomeFragment : Fragment(), HomeNavigation {
    override fun navigateToUserDetail(userId: String) {
        findNavController().navigate(
            HomeFragmentDirections.actionToUserDetail(userId)
        )
    }
}

// 使用Router进行模块间通信
class AppRouter {
    fun navigateToUserDetail(context: Context, userId: String) {
        val intent = Intent(context, UserDetailActivity::class.java)
        intent.putExtra("user_id", userId)
        context.startActivity(intent)
    }
}

依赖管理

1. 依赖注入

使用Hilt/Dagger

// 定义Module
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    @Singleton
    fun provideApiService(): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .build()
            .create(ApiService::class.java)
    }
    
    @Provides
    @Singleton
    fun provideUserRepository(
        apiService: ApiService
    ): UserRepository {
        return UserRepositoryImpl(apiService)
    }
}

// 注入依赖
@AndroidEntryPoint
class UserActivity : AppCompatActivity() {
    @Inject
    lateinit var userRepository: UserRepository
    
    // ...
}

手动依赖注入

// 依赖容器
class AppContainer {
    private val apiService: ApiService by lazy {
        Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .build()
            .create(ApiService::class.java)
    }
    
    val userRepository: UserRepository by lazy {
        UserRepositoryImpl(apiService)
    }
}

// 在Application中初始化
class MyApplication : Application() {
    val appContainer = AppContainer()
}

// 在Activity中使用
class UserActivity : AppCompatActivity() {
    private lateinit var userRepository: UserRepository
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        userRepository = (application as MyApplication)
            .appContainer.userRepository
    }
}

2. 依赖版本管理

统一版本管理

// buildSrc/src/main/kotlin/Dependencies.kt
object Versions {
    const val kotlin = "1.9.0"
    const val androidxCore = "1.9.0"
    const val androidxAppCompat = "1.6.1"
    const val material = "1.8.0"
    const val hilt = "2.44"
}

object Dependencies {
    const val kotlinStdlib = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}"
    const val androidxCoreKtx = "androidx.core:core-ktx:${Versions.androidxCore}"
    const val androidxAppCompat = "androidx.appcompat:appcompat:${Versions.androidxAppCompat}"
    const val material = "com.google.android.material:material:${Versions.material}"
    const val hiltAndroid = "com.google.dagger:hilt-android:${Versions.hilt}"
}

// 在模块中使用
dependencies {
    implementation(Dependencies.kotlinStdlib)
    implementation(Dependencies.androidxCoreKtx)
    implementation(Dependencies.androidxAppCompat)
    implementation(Dependencies.material)
}

架构模式选择

1. MVVM模式

MVVM实现

// Model数据模型
data class User(
    val id: String,
    val name: String
)

// ViewModelUI逻辑
class UserViewModel(
    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
    
    fun loadUser(userId: String) {
        viewModelScope.launch {
            _loading.value = true
            try {
                val user = repository.getUser(userId)
                _user.value = user
            } catch (e: Exception) {
                // 处理错误
            } finally {
                _loading.value = false
            }
        }
    }
}

// ViewUI
class UserActivity : AppCompatActivity() {
    private lateinit var viewModel: UserViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)
        
        viewModel = ViewModelProvider(this)[UserViewModel::class.java]
        
        viewModel.user.observe(this) { user ->
            // 更新UI
            nameTextView.text = user.name
        }
        
        viewModel.loading.observe(this) { isLoading ->
            progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
        }
    }
}

2. MVI模式

MVI实现

// StateUI状态
data class UserState(
    val user: User? = null,
    val isLoading: Boolean = false,
    val error: String? = null
)

// Intent用户意图
sealed class UserIntent {
    object LoadUser : UserIntent()
    data class RefreshUser(val userId: String) : UserIntent()
}

// ViewModel
class UserViewModel(
    private val repository: UserRepository
) : ViewModel() {
    private val _state = MutableStateFlow(UserState())
    val state: StateFlow<UserState> = _state.asStateFlow()
    
    fun handleIntent(intent: UserIntent) {
        when (intent) {
            is UserIntent.LoadUser -> loadUser()
            is UserIntent.RefreshUser -> refreshUser(intent.userId)
        }
    }
    
    private fun loadUser() {
        viewModelScope.launch {
            _state.value = _state.value.copy(isLoading = true)
            try {
                val user = repository.getUser()
                _state.value = _state.value.copy(
                    user = user,
                    isLoading = false
                )
            } catch (e: Exception) {
                _state.value = _state.value.copy(
                    error = e.message,
                    isLoading = false
                )
            }
        }
    }
}

3. Clean Architecture + MVVM

组合使用

// Domain Layer
interface UserRepository {
    suspend fun getUser(userId: String): User
}

class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(userId: String): Result<User> {
        return try {
            Result.success(repository.getUser(userId))
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}

// Presentation Layer (MVVM)
class UserViewModel(
    private val getUserUseCase: GetUserUseCase
) : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    
    fun loadUser(userId: String) {
        viewModelScope.launch {
            when (val result = getUserUseCase(userId)) {
                is Result.Success -> _user.value = result.data
                is Result.Failure -> {
                    // 处理错误
                }
            }
        }
    }
}

Jetpack架构组件

1. ViewModel

使用ViewModel

class UserViewModel(
    private val repository: UserRepository
) : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    
    init {
        loadUser()
    }
    
    private fun loadUser() {
        viewModelScope.launch {
            val user = repository.getUser()
            _user.value = user
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        // 清理资源
    }
}

2. LiveData

使用LiveData

class UserViewModel : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    
    private val _error = MutableLiveData<String?>()
    val error: LiveData<String?> = _error
    
    fun loadUser() {
        viewModelScope.launch {
            try {
                val user = repository.getUser()
                _user.value = user
                _error.value = null
            } catch (e: Exception) {
                _error.value = e.message
            }
        }
    }
}

// 在Activity中观察
viewModel.user.observe(this) { user ->
    // 更新UI
}

viewModel.error.observe(this) { error ->
    error?.let {
        // 显示错误
    }
}

3. Room数据库

使用Room

// Entity
@Entity(tableName = "users")
data class UserEntity(
    @PrimaryKey val id: String,
    val name: String,
    val email: String
)

// DAO
@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :userId")
    suspend fun getUser(userId: String): UserEntity?
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: UserEntity)
    
    @Delete
    suspend fun deleteUser(user: UserEntity)
}

// Database
@Database(entities = [UserEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

4. WorkManager

使用WorkManager

// 定义Worker
class SyncWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        return try {
            // 执行后台任务
            syncData()
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

// 调度任务
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(syncRequest)

总结

良好的应用架构应该遵循以下原则:

  1. 关注点分离:每个组件只负责一个职责
  2. 依赖倒置:依赖接口而非实现
  3. 分层架构:清晰的分层结构,便于维护和测试
  4. 模块化设计:功能模块化,提高可复用性
  5. 依赖管理:使用依赖注入,管理依赖关系
  6. 架构模式:根据项目需求选择合适的架构模式
  7. Jetpack组件充分利用Jetpack架构组件

通过遵循这些最佳实践可以构建出高质量、可维护、可扩展的Android应用。