You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.5 KiB
7.5 KiB
ScannerView 代码重构说明
🎯 重构目标
将原本庞大、复杂的 ScannerView.swift
文件重构为更加模块化、可维护和可读的代码结构。
🔄 重构前后对比
重构前
- 文件大小: 约 700+ 行代码
- 结构: 所有代码都在一个巨大的
ScannerView
中 - 可读性: 难以理解和维护
- 复用性: 组件无法独立使用
- 测试性: 难以进行单元测试
重构后
- 文件大小: 约 600+ 行代码(更清晰的结构)
- 结构: 分解为多个独立的组件
- 可读性: 每个组件职责单一,易于理解
- 复用性: 组件可以独立使用和测试
- 测试性: 每个组件都可以独立测试
🏗️ 新的代码结构
1. 主扫描视图 (ScannerView
)
struct ScannerView: View {
// 主要状态管理
// 协调各个子组件
// 处理业务逻辑
}
职责:
- 管理整体状态
- 协调子组件
- 处理条码检测逻辑
- 管理生命周期
2. 扫描界面覆盖层 (ScanningOverlayView
)
struct ScanningOverlayView: View {
// 扫描线显示
// 提示文本
// 底部按钮
}
职责:
- 显示扫描界面元素
- 管理扫描线样式
- 显示用户提示
3. 扫描指令视图 (ScanningInstructionView
)
struct ScanningInstructionView: View {
// 根据状态显示不同提示
// 单个条码 vs 多个条码
}
职责:
- 显示扫描状态提示
- 动态更新提示内容
4. 扫描底部按钮视图 (ScanningBottomButtonsView
)
struct ScanningBottomButtonsView: View {
// 扫描线样式选择器
// 重新扫描按钮
// 关闭按钮
}
职责:
- 管理底部按钮区域
- 处理用户交互
5. 扫描线样式选择器 (ScanningStyleSelectorView
)
struct ScanningStyleSelectorView: View {
// 5种扫描线样式选择
// 实时预览效果
}
职责:
- 提供扫描线样式选择
- 显示当前选中状态
6. 测试自动选择按钮 (TestAutoSelectButton
)
struct TestAutoSelectButton: View {
// 调试用的测试按钮
// 模拟自动选择功能
}
职责:
- 提供调试功能
- 测试自动选择逻辑
7. 相机预览视图 (CameraPreviewView
)
struct CameraPreviewView: UIViewRepresentable {
// 集成 AVFoundation
// 管理预览层
}
职责:
- 集成 UIKit 相机预览
- 管理预览层生命周期
8. 扫描器视图模型 (ScannerViewModel
)
class ScannerViewModel: ObservableObject {
// 相机会话管理
// 条码检测处理
// 状态管理
}
职责:
- 管理 AVFoundation 会话
- 处理条码检测
- 管理检测状态
9. 条码位置标记覆盖层 (CodePositionOverlay
)
struct CodePositionOverlay: View {
// 显示检测到的条码位置
// 支持点击选择
}
职责:
- 显示条码位置标记
- 处理用户选择
10. 单个条码位置标记 (CodePositionMarker
)
struct CodePositionMarker: View {
// 单个条码的视觉标记
// 坐标计算和转换
}
职责:
- 显示单个条码标记
- 计算屏幕坐标
- 处理点击事件
11. 扫描线视图 (ScanningLineView
)
struct ScanningLineView: View {
// 根据样式显示不同扫描线
// 支持5种不同风格
}
职责:
- 根据样式显示扫描线
- 管理动画效果
12. 各种扫描线样式
- 现代扫描线 (
ModernScanningLine
): 蓝色渐变,带阴影 - 经典扫描线 (
ClassicScanningLine
): 简单绿色线条 - 霓虹扫描线 (
NeonScanningLine
): 紫色,带发光效果 - 极简扫描线 (
MinimalScanningLine
): 白色细线 - 复古扫描线 (
RetroScanningLine
): 橙色点状线条
🎨 设计模式应用
1. 组合模式 (Composition)
- 主视图由多个子组件组合而成
- 每个组件职责单一,易于维护
2. 策略模式 (Strategy)
- 扫描线样式通过枚举和策略实现
- 可以轻松添加新的扫描线样式
3. 观察者模式 (Observer)
- 使用
@Published
和@StateObject
实现数据绑定 - 组件间通过数据流通信
4. 工厂模式 (Factory)
ScanningLineView
根据样式创建对应的扫描线组件
🔧 技术改进
1. 代码组织
- 使用
MARK:
注释清晰分组 - 相关功能放在一起
- 逻辑流程更清晰
2. 状态管理
- 状态分散到各个组件
- 减少主视图的复杂度
- 更好的状态隔离
3. 错误处理
- 统一的错误处理机制
- 更好的用户反馈
4. 性能优化
- 组件按需渲染
- 减少不必要的重绘
📱 用户体验改进
1. 视觉一致性
- 统一的视觉风格
- 更好的动画效果
- 清晰的视觉层次
2. 交互反馈
- 即时的用户反馈
- 清晰的状态指示
- 直观的操作流程
3. 可访问性
- 更好的触摸区域
- 清晰的视觉标记
- 一致的交互模式
🧪 测试友好性
1. 单元测试
- 每个组件可以独立测试
- 清晰的输入输出接口
- 可预测的行为
2. 集成测试
- 组件间接口清晰
- 数据流容易追踪
- 错误场景容易模拟
3. UI测试
- 组件结构清晰
- 交互逻辑简单
- 状态变化可预测
🚀 扩展性
1. 新功能添加
- 可以轻松添加新的扫描线样式
- 可以添加新的UI组件
- 可以扩展扫描功能
2. 样式定制
- 扫描线样式完全可定制
- 颜色、尺寸、动画都可调整
- 支持主题切换
3. 平台适配
- 组件可以轻松适配其他平台
- 核心逻辑与UI分离
- 支持不同的显示方式
📋 重构检查清单
- ✅ 代码分解为独立组件
- ✅ 每个组件职责单一
- ✅ 组件间接口清晰
- ✅ 状态管理优化
- ✅ 错误处理改进
- ✅ 性能优化
- ✅ 代码可读性提升
- ✅ 测试友好性
- ✅ 扩展性增强
- ✅ 文档完善
🔮 未来改进方向
1. 进一步模块化
- 将扫描线样式提取到独立文件
- 创建专门的动画管理器
- 添加配置管理组件
2. 性能优化
- 添加懒加载机制
- 优化动画性能
- 减少内存占用
3. 功能扩展
- 支持更多条码类型
- 添加历史记录功能
- 支持批量扫描
4. 国际化
- 支持更多语言
- 动态语言切换
- 本地化资源管理
📚 使用说明
1. 基本使用
struct ContentView: View {
var body: some View {
ScannerView()
}
}
2. 自定义扫描线样式
@State private var selectedStyle: ScanningLineStyle = .modern
ScanningLineView(style: selectedStyle)
3. 添加新的扫描线样式
enum ScanningLineStyle: String, CaseIterable {
case custom = "style_custom"
var localizedName: String {
switch self {
case .custom: return "自定义样式".localized
}
}
}
struct CustomScanningLine: View {
var body: some View {
// 自定义扫描线实现
}
}
🎉 总结
通过这次重构,我们成功地将一个复杂的单体视图转换为多个职责清晰、易于维护的组件。重构后的代码具有以下优势:
- 可读性: 每个组件都有明确的职责和清晰的接口
- 可维护性: 修改某个功能只需要修改对应的组件
- 可测试性: 每个组件都可以独立测试
- 可扩展性: 添加新功能变得简单
- 可复用性: 组件可以在其他地方复用
这次重构为项目的长期维护和功能扩展奠定了坚实的基础。