mxivideo/docs/code-refactoring-analysis.md

8.4 KiB
Raw Permalink Blame History

代码重构分析从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%

可维护性提升

重构前问题

  • 代码重复,修改需要多处同步
  • 错误处理不一致
  • 参数解析容易出错
  • 测试困难,需要模拟整个服务

重构后优势

  • 单一职责,修改只需一处
  • 统一的错误处理逻辑
  • 声明式配置,不易出错
  • 独立测试,覆盖率更高

复用性分析

可复用的通用函数

  1. DependencyChecker: 适用于所有需要可选依赖的服务
  2. CommandLineParser: 适用于所有命令行工具
  3. JSONRPCHandler: 适用于所有JSON-RPC服务
  4. FileUtils: 适用于所有文件处理场景
  5. 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%: 大幅减少重复代码
  • 可维护性提升: 单一职责,易于修改
  • 复用性增强: 通用函数可在多个服务中使用
  • 测试覆盖: 独立测试,更高的代码质量
  • 开发效率: 新服务开发更快

最佳实践

  1. 识别重复模式: 寻找在多个地方重复的代码
  2. 抽象通用逻辑: 提取可复用的功能
  3. 保持简单: 通用函数应该简单易用
  4. 完善测试: 为通用函数编写充分的测试
  5. 文档完善: 提供清晰的使用示例

下一步计划

  1. 将通用函数应用到其他服务
  2. 继续识别新的可抽象模式
  3. 建立服务开发模板
  4. 完善工具函数库

通过这次重构,我们不仅减少了代码重复,还建立了一套可复用的工具函数库,为后续的服务开发奠定了良好的基础!


代码重构 - 让开发更高效,维护更简单!