# 模板方法模式 + Flow 实践

# 模板方法模式 + 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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值