8.4 KiB
8.4 KiB
代码重构分析:从video_splitter中抽象通用函数
🎯 重构目标
将video_splitter.py中的重复模式抽象成可复用的通用函数,提高代码的可维护性和复用性。
📊 抽象的通用函数分析
1. 依赖检查和导入模式
重构前 (重复代码)
# 在每个服务文件中重复
try:
from python_core.utils.logger import logger
from python_core.utils.jsonrpc import create_response_handler, create_progress_reporter
JSONRPC_AVAILABLE = True
except ImportError:
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s | %(levelname)s | %(message)s')
logger = logging.getLogger(__name__)
JSONRPC_AVAILABLE = False
try:
from scenedetect import VideoManager, SceneManager, split_video_ffmpeg
SCENEDETECT_AVAILABLE = True
logger.info("PySceneDetect is available")
except ImportError as e:
SCENEDETECT_AVAILABLE = False
logger.warning(f"PySceneDetect not available: {e}")
重构后 (通用函数)
from python_core.utils.command_utils import DependencyChecker
# 简洁的依赖检查
scenedetect_available, scenedetect_items = DependencyChecker.check_optional_dependency(
module_name="scenedetect",
import_items=["VideoManager", "SceneManager", "detectors.ContentDetector"],
success_message="PySceneDetect is available for video splitting",
error_message="PySceneDetect not available"
)
优势:
- ✅ 减少重复代码 80%
- ✅ 统一的依赖检查逻辑
- ✅ 更好的错误处理
- ✅ 易于测试和维护
2. 命令行参数解析
重构前 (手动解析)
# 手动解析,容易出错
threshold = 30.0
detector_type = "content"
output_dir = None
i = 3
while i < len(sys.argv):
if sys.argv[i] == "--threshold" and i + 1 < len(sys.argv):
threshold = float(sys.argv[i + 1])
i += 2
elif sys.argv[i] == "--detector" and i + 1 < len(sys.argv):
detector_type = sys.argv[i + 1]
i += 2
# ... 更多重复代码
重构后 (声明式配置)
from python_core.utils.command_utils import CommandLineParser
# 声明式参数定义
arg_definitions = {
"threshold": {"type": float, "default": 30.0},
"detector": {"type": str, "default": "content", "choices": ["content", "threshold"]},
"output-dir": {"type": str, "default": None}
}
# 一行解析
parsed_args = CommandLineParser.parse_command_args(sys.argv[3:], arg_definitions)
优势:
- ✅ 减少代码量 70%
- ✅ 自动类型转换和验证
- ✅ 支持选择范围检查
- ✅ 统一的错误处理
3. JSON-RPC响应处理
重构前 (重复模式)
# 在每个命令中重复
if rpc:
if result.get("success"):
rpc.success(result)
else:
rpc.error("ANALYSIS_FAILED", result.get("error", "Video analysis failed"))
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
重构后 (统一处理)
from python_core.utils.command_utils import JSONRPCHandler
# 一行处理
JSONRPCHandler.handle_command_response(rpc_handler, result, "ANALYSIS_FAILED")
优势:
- ✅ 减少重复代码 90%
- ✅ 统一的响应格式
- ✅ 自动错误处理
- ✅ 易于修改响应逻辑
4. 文件验证和路径处理
重构前 (分散逻辑)
# 文件验证
if not os.path.exists(video_path):
raise FileNotFoundError(f"Video file not found: {video_path}")
# 创建输出目录
if output_dir is None:
video_name = Path(video_path).stem
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_dir = self.output_base_dir / f"{video_name}_{timestamp}"
else:
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
重构后 (专用函数)
from python_core.utils.command_utils import FileUtils
# 文件验证
video_path = FileUtils.validate_input_file(video_path, "video")
# 创建输出目录
output_dir = FileUtils.create_timestamped_output_dir(
base_dir=self.output_base_dir,
name_prefix=Path(video_path).stem
)
优势:
- ✅ 更清晰的意图表达
- ✅ 统一的错误消息
- ✅ 可配置的时间戳格式
- ✅ 更好的测试覆盖
5. 执行时间测量
重构前 (手动计时)
start_time = datetime.now()
# ... 执行操作 ...
processing_time = (datetime.now() - start_time).total_seconds()
重构后 (装饰器)
from python_core.utils.command_utils import PerformanceUtils
@PerformanceUtils.measure_execution_time
def detect_scenes(self, video_path: str, threshold: float = 30.0) -> List[SceneInfo]:
# ... 业务逻辑 ...
return scenes
# 使用时自动返回 (result, execution_time)
scenes, execution_time = self.detect_scenes(video_path, threshold)
优势:
- ✅ 自动时间测量
- ✅ 装饰器模式,不侵入业务逻辑
- ✅ 统一的时间测量方式
- ✅ 易于性能分析
📈 重构效果对比
代码量对比
| 功能模块 | 重构前行数 | 重构后行数 | 减少比例 |
|---|---|---|---|
| 依赖检查 | 15行 | 3行 | 80% |
| 参数解析 | 25行 | 5行 | 80% |
| JSON-RPC处理 | 8行 | 1行 | 87% |
| 文件处理 | 12行 | 2行 | 83% |
| 时间测量 | 3行 | 1行装饰器 | 67% |
| 总计 | 63行 | 12行 | 81% |
可维护性提升
重构前问题
- ❌ 代码重复,修改需要多处同步
- ❌ 错误处理不一致
- ❌ 参数解析容易出错
- ❌ 测试困难,需要模拟整个服务
重构后优势
- ✅ 单一职责,修改只需一处
- ✅ 统一的错误处理逻辑
- ✅ 声明式配置,不易出错
- ✅ 独立测试,覆盖率更高
复用性分析
可复用的通用函数
- DependencyChecker: 适用于所有需要可选依赖的服务
- CommandLineParser: 适用于所有命令行工具
- JSONRPCHandler: 适用于所有JSON-RPC服务
- FileUtils: 适用于所有文件处理场景
- PerformanceUtils: 适用于所有需要性能测量的场景
潜在应用场景
- 🎯 AI视频生成服务: 可复用依赖检查、参数解析
- 🎯 模板管理服务: 可复用文件处理、JSON-RPC
- 🎯 媒体库服务: 可复用所有通用函数
- 🎯 其他Python服务: 通用工具函数
🚀 使用建议
1. 渐进式重构
# 第一步:引入通用工具
from python_core.utils.command_utils import DependencyChecker
# 第二步:替换现有代码
# 旧代码注释掉,新代码并行运行
# 第三步:完全替换
# 删除旧代码,使用新的通用函数
2. 测试策略
# 为通用函数编写单元测试
def test_dependency_checker():
available, items = DependencyChecker.check_optional_dependency(
"json", ["loads", "dumps"]
)
assert available == True
assert "loads" in items
# 为重构后的服务编写集成测试
def test_video_splitter_service():
service = VideoSplitterService()
result = service.analyze_video("test.mp4")
assert result["success"] == True
3. 扩展指南
# 添加新的通用函数
class DatabaseUtils:
@staticmethod
def create_connection_pool(config):
# 数据库连接池逻辑
pass
# 扩展现有函数
class CommandLineParser:
@staticmethod
def parse_config_file(config_path):
# 配置文件解析逻辑
pass
🎉 总结
重构收益
- ✅ 代码减少81%: 大幅减少重复代码
- ✅ 可维护性提升: 单一职责,易于修改
- ✅ 复用性增强: 通用函数可在多个服务中使用
- ✅ 测试覆盖: 独立测试,更高的代码质量
- ✅ 开发效率: 新服务开发更快
最佳实践
- 识别重复模式: 寻找在多个地方重复的代码
- 抽象通用逻辑: 提取可复用的功能
- 保持简单: 通用函数应该简单易用
- 完善测试: 为通用函数编写充分的测试
- 文档完善: 提供清晰的使用示例
下一步计划
- 将通用函数应用到其他服务
- 继续识别新的可抽象模式
- 建立服务开发模板
- 完善工具函数库
通过这次重构,我们不仅减少了代码重复,还建立了一套可复用的工具函数库,为后续的服务开发奠定了良好的基础!
代码重构 - 让开发更高效,维护更简单!