# 模板方法模式 + Flow 实践
## 📋 目录
1. [设计概述](#设计概述)
2. [核心原则](#核心原则)
3. [基础实现](#基础实现)
4. [流程中断处理](#流程中断处理)
5. [异常场景处理](#异常场景处理)
6. [最佳实践](#最佳实践)
7. [完整示例](#完整示例)
8. [常见问题](#常见问题)
---
## 🎯 设计概述
### 模板方法模式的核心
```
模板方法模式的核心原则:
1. 定义算法的骨架(流程结构)
2. 将具体步骤延迟到子类实现
3. 不携带处理的数据(数据通过参数和返回值传递)
4. 单一职责:模板只负责流程结构,不负责数据处理
```
### Flow 的作用
```
Flow 在模板方法模式中的作用:
1. 数据流式传递:数据通过 Flow 传递,不在模板中存储
2. 链式操作:使用 flatMapConcat 串联步骤
3. 自动中断处理:Flow 取消时自动处理流程中断
4. 统一错误处理:catch 统一处理错误
```
---
## 💡 核心原则
### 原则1:模板不携带数据
```kotlin
// ✅ 正确:数据通过参数和返回值传递
abstract class SyncTemplate {
suspend fun executeSync(context: Context): Result {
val data1 = step1(context) // ✅ 返回数据,不存储
val data2 = step2(context, data1) // ✅ 传入参数,返回数据
val data3 = step3(context, data2) // ✅ 数据在流程中传递
return step4(context, data3)
}
protected abstract suspend fun step1(context: Context): Data1
protected abstract suspend fun step2(context: Context, data1: Data1): Data2
}
// ❌ 错误:模板携带数据
abstract class SyncTemplate {
private var data1: Data1? = null // ❌ 不应该存储数据
suspend fun executeSync(): Result {
data1 = step1() // ❌ 数据存储在模板中
}
}
```
### 原则2:数据流式传递
```kotlin
// ✅ 正确:数据通过 Flow 传递
fun executeSync(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ctx -> step1Flow(ctx) } // ✅ Flow<Data1>
.flatMapConcat { data1 -> step2Flow(data1) } // ✅ Flow<Data2>
.flatMapConcat { data2 -> step3Flow(data2) } // ✅ 数据自动传递
.flatMapConcat { data3 -> step4Flow(data3) } // ✅ 返回 Flow<Result>
}
```
### 原则3:自动中断处理
```kotlin
// ✅ Flow 自动处理流程中断
fun executeSync(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.catch { e ->
// ✅ 错误中断:自动处理
cleanup(context)
emit(Result.Failed(e))
}
.onCompletion { cause ->
// ✅ 完成或中断:自动清理
if (cause != null) {
cleanup(context) // ✅ 流程中断时自动清理
}
}
}
```
---
## 🔧 基础实现
### 基础模板类
```kotlin
/**
* ✅ 模板方法模式 + Flow 基础实现
*
* 设计要点:
* 1. 模板不携带数据,数据通过参数和返回值传递
* 2. 每个步骤返回 Flow,数据在 Flow 中传递
* 3. 流程中断通过 Flow 的取消机制自动处理
* 4. 错误处理通过 catch 统一处理
*/
abstract class FlowTemplate<T : Context> {
private val TAG = this::class.simpleName ?: "FlowTemplate"
/**
* ✅ 模板方法:定义算法骨架
*
* 数据流:
* Context → Data1 → Data2 → Data3 → Result
*/
fun execute(context: T): Flow<Result> {
return flowOf(context)
// ✅ 步骤1:准备
.flatMapConcat { ctx -> prepareFlow(ctx) }
// ✅ 步骤2:获取数据1
.flatMapConcat { ctx -> step1Flow(ctx) }
// ✅ 步骤3:获取数据2(使用数据1)
.flatMapConcat { (ctx, data1) -> step2Flow(ctx, data1) }
// ✅ 步骤4:处理数据(使用数据1和数据2)
.flatMapConcat { (ctx, data1, data2) -> step3Flow(ctx, data1, data2) }
// ✅ 步骤5:完成(使用处理结果)
.flatMapConcat { (ctx, result) -> step4Flow(ctx, result) }
// ✅ 错误处理(统一处理所有错误)
.catch { e ->
handleError(context, e)
emit(Result.Failed(e, "Execution failed: ${e.message}"))
}
// ✅ 资源清理(完成或中断时自动清理)
.onCompletion { cause ->
if (cause != null) {
// ✅ 流程中断(取消或错误)时清理
cleanup(context)
}
}
}
/**
* ✅ 准备步骤(模板方法,子类可重写)
*/
protected open fun prepareFlow(context: T): Flow<T> {
Logger.i(TAG, "Preparing execution...")
return flowOf(context)
}
/**
* ✅ 步骤1:获取数据1(抽象方法,子类必须实现)
*/
protected abstract fun step1Flow(context: T): Flow<Pair<T, Data1>>
/**
* ✅ 步骤2:获取数据2(抽象方法,子类必须实现)
*/
protected abstract fun step2Flow(context: T, data1: Data1): Flow<Triple<T, Data1, Data2>>
/**
* ✅ 步骤3:处理数据(抽象方法,子类必须实现)
*/
protected abstract fun step3Flow(
context: T,
data1: Data1,
data2: Data2
): Flow<Pair<T, ProcessResult>>
/**
* ✅ 步骤4:完成(抽象方法,子类必须实现)
*/
protected abstract fun step4Flow(
context: T,
result: ProcessResult
): Flow<Result>
/**
* ✅ 错误处理(模板方法,子类可重写)
*/
protected open fun handleError(context: T, error: Throwable) {
Logger.e(TAG, "Error in execution: ${error.message}")
cleanup(context)
}
/**
* ✅ 清理资源(模板方法,子类可重写)
*/
protected open fun cleanup(context: T) {
Logger.i(TAG, "Cleaning up resources...")
}
}
```
### 数据传递方式
```kotlin
/**
* ✅ 方式1:使用 Pair/Triple(简单场景)
*/
fun execute(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ctx -> step1Flow(ctx) } // Flow<Pair<Context, Data1>>
.flatMapConcat { (ctx, data1) -> step2Flow(ctx, data1) } // Flow<Triple<Context, Data1, Data2>>
.flatMapConcat { (ctx, data1, data2) -> step3Flow(ctx, data1, data2) }
}
/**
* ✅ 方式2:使用数据类(复杂场景,推荐)
*/
data class ExecutionState<T : Context>(
val context: T,
val data1: Data1? = null,
val data2: Data2? = null,
val result: ProcessResult? = null
)
fun execute(context: Context): Flow<Result> {
return flowOf(ExecutionState(context))
.flatMapConcat { state -> step1Flow(state) } // Flow<ExecutionState>
.flatMapConcat { state -> step2Flow(state) } // Flow<ExecutionState>
.flatMapConcat { state -> step3Flow(state) } // Flow<ExecutionState>
.flatMapConcat { state -> extractResult(state) } // Flow<Result>
}
```
---
## 🔄 流程中断处理
### 1. 协程取消(自动处理)
```kotlin
/**
* ✅ 协程取消:Flow 自动处理
*/
fun execute(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.onCompletion { cause ->
// ✅ cause != null 表示流程中断(取消或错误)
if (cause != null) {
Logger.d(TAG, "Execution cancelled: ${cause.message}")
cleanup(context) // ✅ 自动清理
}
}
}
// ✅ 使用示例:取消时自动处理
lifecycleScope.launch {
template.execute(context)
.collect { result ->
// 如果协程被取消(例如 Fragment 销毁),Flow 自动取消
// onCompletion 自动执行清理
}
}
// ✅ 手动取消
val job = scope.launch {
template.execute(context).collect { ... }
}
job.cancel() // ✅ Flow 自动取消,onCompletion 自动清理
```
### 2. 超时中断
```kotlin
/**
* ✅ 超时中断处理
*/
fun executeWithTimeout(
context: Context,
timeoutMillis: Long = 30000
): Flow<Result> {
return execute(context)
.timeout(timeoutMillis) // ✅ 超时自动中断
.catch { e ->
when (e) {
is TimeoutCancellationException -> {
Logger.w(TAG, "Execution timeout after ${timeoutMillis}ms")
cleanup(context)
emit(Result.Failed(e, "Execution timeout"))
}
else -> {
handleError(context, e)
emit(Result.Failed(e, "Execution failed: ${e.message}"))
}
}
}
}
```
### 3. 条件中断
```kotlin
/**
* ✅ 条件中断处理
*/
fun executeWithCondition(
context: Context,
shouldContinue: (Context) -> Boolean
): Flow<Result> {
return execute(context)
.takeWhile { result ->
// ✅ 条件检查:如果不满足条件,中断流程
shouldContinue(context)
}
.catch { e ->
Logger.w(TAG, "Execution cancelled by condition")
cleanup(context)
emit(Result.Failed(e, "Execution cancelled by condition"))
}
}
```
### 4. 步骤级中断
```kotlin
/**
* ✅ 步骤级中断处理(在某个步骤中中断)
*/
abstract class FlowTemplate<T : Context> {
protected fun step1Flow(context: T): Flow<Pair<T, Data1>> {
return flow {
// ✅ 检查中断条件
if (shouldInterrupt(context)) {
throw InterruptedException("Interrupted by condition")
}
// ✅ 执行步骤
val data1 = performStep1(context)
emit(Pair(context, data1))
}
}
/**
* ✅ 检查是否应该中断(模板方法,子类可重写)
*/
protected open fun shouldInterrupt(context: T): Boolean {
return false // 默认不中断
}
}
```
---
## ⚠️ 异常场景处理
### 1. 数据错误处理
```kotlin
/**
* ✅ 数据错误处理(验证数据有效性)
*/
abstract class FlowTemplate<T : Context> {
protected fun step1Flow(context: T): Flow<Pair<T, Data1>> {
return flow {
val data1 = performStep1(context)
// ✅ 验证数据有效性
validateData1(data1)?.let { error ->
throw DataValidationException(error)
}
emit(Pair(context, data1))
}
}
/**
* ✅ 验证数据(模板方法,子类可重写)
*/
protected open fun validateData1(data1: Data1): String? {
// 默认验证逻辑
return if (data1.isValid()) null else "Data1 is invalid"
}
/**
* ✅ 数据验证异常处理
*/
override fun handleError(context: T, error: Throwable) {
when (error) {
is DataValidationException -> {
Logger.w(TAG, "Data validation failed: ${error.message}")
// ✅ 数据错误,不需要清理,只记录日志
}
else -> {
super.handleError(context, error)
}
}
}
}
```
### 2. 网络错误处理
```kotlin
/**
* ✅ 网络错误处理(重试机制)
*/
abstract class FlowTemplate<T : Context> {
protected fun step2Flow(context: T, data1: Data1): Flow<Triple<T, Data1, Data2>> {
return flow {
// ✅ 重试机制
val data2 = retryWithBackoff(
maxRetries = 3,
initialDelay = 1000L
) {
performStep2(context, data1)
}
emit(Triple(context, data1, data2))
}
.catch { e ->
when (e) {
is NetworkException -> {
Logger.w(TAG, "Network error, retrying...")
// ✅ 网络错误,可以重试
throw e
}
else -> {
throw e
}
}
}
}
/**
* ✅ 重试机制(指数退避)
*/
private suspend fun <T> retryWithBackoff(
maxRetries: Int,
initialDelay: Long,
block: suspend () -> T
): T {
var delay = initialDelay
repeat(maxRetries) { attempt ->
try {
return block()
} catch (e: NetworkException) {
if (attempt == maxRetries - 1) throw e
delay(delay)
delay *= 2 // 指数退避
}
}
throw IllegalStateException("Should not reach here")
}
}
```
### 3. 空数据处理
```kotlin
/**
* ✅ 空数据处理(优雅降级)
*/
abstract class FlowTemplate<T : Context> {
protected fun step2Flow(context: T, data1: Data1): Flow<Triple<T, Data1, Data2>> {
return flow {
val data2 = performStep2(context, data1)
// ✅ 处理空数据
if (data2 == null) {
Logger.w(TAG, "Data2 is null, using default value")
val defaultData2 = getDefaultData2(context, data1)
emit(Triple(context, data1, defaultData2))
} else {
emit(Triple(context, data1, data2))
}
}
}
/**
* ✅ 获取默认数据(模板方法,子类可重写)
*/
protected open fun getDefaultData2(context: T, data1: Data1): Data2 {
// 子类可以提供默认值
throw IllegalStateException("Data2 is required but not available")
}
}
```
### 4. 并发冲突处理
```kotlin
/**
* ✅ 并发冲突处理(使用 Mutex)
*/
abstract class FlowTemplate<T : Context> {
private val executionMutex = Mutex()
fun execute(context: T): Flow<Result> {
return flow {
// ✅ 使用 Mutex 防止并发执行
executionMutex.withLock {
emitAll(executeInternal(context))
}
}
}
private fun executeInternal(context: T): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
}
}
```
### 5. 资源泄漏处理
```kotlin
/**
* ✅ 资源泄漏处理(确保资源清理)
*/
abstract class FlowTemplate<T : Context> {
protected fun step2Flow(context: T, data1: Data1): Flow<Triple<T, Data1, Data2>> {
return flow {
val resource = acquireResource(context)
try {
val data2 = performStep2(resource, data1)
emit(Triple(context, data1, data2))
} finally {
// ✅ 确保资源释放(即使发生异常)
releaseResource(resource)
}
}
}
/**
* ✅ 获取资源(抽象方法)
*/
protected abstract fun acquireResource(context: T): Resource
/**
* ✅ 释放资源(抽象方法)
*/
protected abstract fun releaseResource(resource: Resource)
}
```
---
## 🎯 最佳实践
### 1. 简洁的数据传递
```kotlin
// ✅ 推荐:使用数据类封装状态(清晰、简洁)
data class ExecutionState<T : Context>(
val context: T,
val step1Result: Step1Result? = null,
val step2Result: Step2Result? = null,
val step3Result: Step3Result? = null
)
fun execute(context: Context): Flow<Result> {
return flowOf(ExecutionState(context))
.flatMapConcat { state -> step1Flow(state) } // 返回 ExecutionState
.flatMapConcat { state -> step2Flow(state) } // 返回 ExecutionState
.flatMapConcat { state -> step3Flow(state) } // 返回 ExecutionState
.map { state -> extractResult(state) } // 提取最终结果
}
// ❌ 不推荐:使用深层嵌套的 Pair/Triple
fun execute(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ctx -> step1Flow(ctx) } // Pair<Context, Data1>
.flatMapConcat { (ctx, d1) -> step2Flow(ctx, d1) } // Triple<Context, Data1, Data2>
.flatMapConcat { (ctx, d1, d2) -> step3Flow(ctx, d1, d2) } // 嵌套过深
}
```
### 2. 统一的错误处理
```kotlin
/**
* ✅ 统一的错误处理(在模板方法中处理)
*/
abstract class FlowTemplate<T : Context> {
fun execute(context: T): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.catch { e ->
// ✅ 统一错误处理
val errorResult = handleError(context, e)
emit(errorResult)
}
}
/**
* ✅ 错误处理(模板方法,子类可重写)
*/
protected open fun handleError(context: T, error: Throwable): Result {
return when (error) {
is DataValidationException -> {
Result.Failed(error, "Data validation failed")
}
is NetworkException -> {
Result.Failed(error, "Network error")
}
is TimeoutCancellationException -> {
Result.Failed(error, "Execution timeout")
}
is CancellationException -> {
Result.Cancelled("Execution cancelled")
}
else -> {
Result.Failed(error, "Unknown error: ${error.message}")
}
}
}
}
```
### 3. 资源清理的保证
```kotlin
/**
* ✅ 资源清理的保证(多重保障)
*/
abstract class FlowTemplate<T : Context> {
fun execute(context: T): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.onCompletion { cause ->
// ✅ 保障1:onCompletion 确保清理(无论成功或失败)
cleanup(context)
}
.catch { e ->
// ✅ 保障2:catch 中清理(错误时)
cleanup(context)
emit(Result.Failed(e))
}
.finally {
// ✅ 保障3:finally 确保清理(协程作用域结束时)
cleanup(context)
}
}
}
```
### 4. 流程监控和日志
```kotlin
/**
* ✅ 流程监控和日志
*/
abstract class FlowTemplate<T : Context> {
fun execute(context: T): Flow<Result> {
return flowOf(context)
.onStart {
Logger.i(TAG, "Execution started: ${context.id}")
}
.flatMapConcat { ctx ->
step1Flow(ctx)
.onEach { Logger.d(TAG, "Step1 completed") }
}
.flatMapConcat { ... }
.onEach { result ->
Logger.i(TAG, "Execution completed: ${result.status}")
}
.onCompletion { cause ->
if (cause == null) {
Logger.i(TAG, "Execution finished successfully")
} else {
Logger.w(TAG, "Execution finished with error: ${cause.message}")
}
}
}
}
```
---
## 📝 完整示例
### 示例:简洁的模板实现
```kotlin
/**
* ✅ 完整的模板实现示例
*/
abstract class SyncFlowTemplate<T : SyncContext> {
private val TAG = this::class.simpleName ?: "SyncFlowTemplate"
/**
* ✅ 模板方法:定义算法骨架
*/
fun executeSync(context: T): Flow<SyncResult> {
return flowOf(context)
// ✅ 步骤1:准备
.flatMapConcat { ctx -> prepareFlow(ctx) }
// ✅ 步骤2:获取本地数据
.flatMapConcat { ctx -> getLocalDataFlow(ctx) }
// ✅ 步骤3:获取云端数据
.flatMapConcat { (ctx, localData) -> getCloudDataFlow(ctx, localData) }
// ✅ 步骤4:比对差异
.flatMapConcat { (ctx, localData, cloudData) ->
compareDifferenceFlow(ctx, localData, cloudData)
}
// ✅ 步骤5:执行同步
.flatMapConcat { (ctx, differences) -> performSyncFlow(ctx, differences) }
// ✅ 步骤6:更新本地
.flatMapConcat { (ctx, syncResult) -> updateLocalFlow(ctx, syncResult) }
// ✅ 错误处理
.catch { e ->
handleError(context, e)
emit(SyncResult.Failed(e, "Sync failed: ${e.message}"))
}
// ✅ 资源清理
.onCompletion { cause ->
if (cause != null) {
cleanup(context)
}
}
}
// ✅ 抽象方法(由子类实现)
protected abstract fun getLocalDataFlow(context: T): Flow<Pair<T, LocalData>>
protected abstract fun getCloudDataFlow(context: T, localData: LocalData): Flow<Triple<T, LocalData, CloudData?>>
protected abstract fun compareDifferenceFlow(context: T, localData: LocalData, cloudData: CloudData?): Flow<Pair<T, Differences>>
protected abstract fun performSyncFlow(context: T, differences: Differences): Flow<Pair<T, SyncResult>>
protected abstract fun updateLocalFlow(context: T, syncResult: SyncResult): Flow<SyncResult>
// ✅ 模板方法(子类可重写)
protected open fun prepareFlow(context: T): Flow<T> = flowOf(context)
protected open fun handleError(context: T, error: Throwable) {
Logger.e(TAG, "Error: ${error.message}")
cleanup(context)
}
protected open fun cleanup(context: T) {
Logger.i(TAG, "Cleaning up")
}
}
/**
* ✅ 具体实现:详情同步
*/
class DetailSyncTemplate(
private val recordId: String
) : SyncFlowTemplate<DetailSyncContext>() {
override fun getLocalDataFlow(context: DetailSyncContext): Flow<Pair<DetailSyncContext, LocalData>> {
return flow {
val localRecord = dbManager.getRecordById(context.fileId)
?: throw IllegalStateException("Record not found")
emit(Pair(context, LocalData(listOf(localRecord))))
}
}
override fun getCloudDataFlow(
context: DetailSyncContext,
localData: LocalData
): Flow<Triple<DetailSyncContext, LocalData, CloudData?>> {
return flow {
val localRecord = localData.records.first()
if (!needSyncDetail(localRecord)) {
emit(Triple(context, localData, null))
return@flow
}
val cloudDetail = syncService.getRecordDetail(recordId)
val cloudData = if (cloudDetail != null) {
CloudData(listOf(cloudDetail))
} else {
null
}
emit(Triple(context, localData, cloudData))
}
}
override fun compareDifferenceFlow(
context: DetailSyncContext,
localData: LocalData,
cloudData: CloudData?
): Flow<Pair<DetailSyncContext, Differences>> {
return flow {
if (cloudData == null) {
emit(Pair(context, Differences.empty()))
return@flow
}
val localRecord = localData.records.first()
val cloudRecord = cloudData.records.first()
val differences = if (cloudRecord.updateAt > localRecord.updateAt) {
Differences(needUpdate = listOf(UpdateItem(localRecord, cloudRecord)))
} else {
Differences.empty()
}
emit(Pair(context, differences))
}
}
override fun performSyncFlow(
context: DetailSyncContext,
differences: Differences
): Flow<Pair<DetailSyncContext, SyncResult>> {
return flow {
if (differences.needUpdate.isEmpty()) {
emit(Pair(context, SyncResult.Success("Already synced", emptyList())))
return@flow
}
val updateItem = differences.needUpdate.first()
val mergedRecord = mergeRecord(updateItem.local, updateItem.cloud)
emit(Pair(context, SyncResult.Success("Synced", listOf(mergedRecord))))
}
}
override fun updateLocalFlow(
context: DetailSyncContext,
syncResult: SyncResult
): Flow<SyncResult> {
return flow {
if (syncResult.records.isNotEmpty()) {
dbManager.updateRecord(syncResult.records.first())
}
emit(syncResult)
}
}
private fun needSyncDetail(record: RecordFile): Boolean {
// 检查是否需要同步详情
val bitmap = AttributeBitmap(record.extAttribute)
return bitmap.recDownSyncState == 1
}
private fun mergeRecord(local: RecordFile, cloud: RecordFile): RecordFile {
// 合并逻辑
return local.copy(
name = cloud.name,
description = cloud.description,
extAttribute = cloud.extAttribute
)
}
}
```
---
## ❓ 常见问题
### Q1: 如何处理流程中断?
**A:**
```kotlin
// ✅ Flow 自动处理流程中断
fun execute(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.onCompletion { cause ->
// ✅ cause != null 表示流程中断
if (cause != null) {
cleanup(context) // ✅ 自动清理
}
}
}
// ✅ 使用时的中断处理
lifecycleScope.launch {
template.execute(context)
.collect { result ->
// 协程取消时,Flow 自动取消,onCompletion 自动清理
}
}
```
### Q2: 如何处理数据错误?
**A:**
```kotlin
// ✅ 数据验证
protected fun step1Flow(context: T): Flow<Pair<T, Data1>> {
return flow {
val data1 = performStep1(context)
// ✅ 验证数据
validateData1(data1)?.let { error ->
throw DataValidationException(error)
}
emit(Pair(context, data1))
}
}
// ✅ 错误处理
.catch { e ->
when (e) {
is DataValidationException -> {
emit(Result.Failed(e, "Data validation failed"))
}
else -> {
emit(Result.Failed(e, "Unknown error"))
}
}
}
```
### Q3: 如何保证资源清理?
**A:**
```kotlin
// ✅ 多重保障
fun execute(context: Context): Flow<Result> {
return flowOf(context)
.flatMapConcat { ... }
.onCompletion { cause ->
// ✅ 保障1:onCompletion
cleanup(context)
}
.catch { e ->
// ✅ 保障2:catch
cleanup(context)
emit(Result.Failed(e))
}
}
```
### Q4: 如何处理超时?
**A:**
```kotlin
// ✅ 超时处理
fun executeWithTimeout(context: Context, timeout: Long = 30000): Flow<Result> {
return execute(context)
.timeout(timeout)
.catch { e ->
when (e) {
is TimeoutCancellationException -> {
cleanup(context)
emit(Result.Failed(e, "Timeout"))
}
else -> {
emit(Result.Failed(e))
}
}
}
}
```
### Q5: 如何传递多个数据?
**A:**
```kotlin
// ✅ 方式1:使用 Pair/Triple(简单场景)
.flatMapConcat { (ctx, data1) -> step2Flow(ctx, data1) } // Pair
// ✅ 方式2:使用数据类(复杂场景,推荐)
data class ExecutionState(
val context: Context,
val data1: Data1? = null,
val data2: Data2? = null
)
.flatMapConcat { state -> step2Flow(state) } // ExecutionState
```
---
## 📚 总结
### 核心原则
1. **模板不携带数据**:数据通过参数和返回值传递
2. **数据流式传递**:数据通过 Flow 传递,不在模板中存储
3. **自动中断处理**:Flow 取消时自动处理流程中断
4. **统一错误处理**:catch 统一处理所有错误
### 流程中断处理
| 中断类型 | 处理方式 | 示例 |
|---------|---------|------|
| **协程取消** | `onCompletion` 自动处理 | `.onCompletion { cleanup() }` |
| **超时中断** | `timeout` 处理 | `.timeout(30000)` |
| **条件中断** | `takeWhile` 处理 | `.takeWhile { condition }` |
| **错误中断** | `catch` 处理 | `.catch { emit(Result.Failed) }` |
### 异常场景处理
| 异常场景 | 处理方式 | 示例 |
|---------|---------|------|
| **数据错误** | 数据验证 + 异常处理 | `validateData()` → `DataValidationException` |
| **网络错误** | 重试机制 | `retryWithBackoff()` |
| **空数据** | 优雅降级 | `getDefaultData()` |
| **并发冲突** | Mutex 保护 | `executionMutex.withLock()` |
| **资源泄漏** | finally 保证 | `try { ... } finally { release() }` |
### 设计优势
- ✅ **简洁**:模板不携带数据,职责单一
- ✅ **自动**:流程中断自动处理,不需要手动管理
- ✅ **统一**:错误处理和资源清理统一处理
- ✅ **灵活**:Flow 链式操作,易于组合和扩展
---
**文档版本**: v1.0
**最后更新**: 2024-01-XX
**作者**: AI Assistant
# 模板方法模式 + Flow 实践
最新推荐文章于 2025-12-18 21:03:42 发布
975

被折叠的 条评论
为什么被折叠?



