ScreenLockDetector/docs/REFACTORING.md

6.2 KiB
Raw Permalink Blame History

ScreenLockDetector 重构说明

概述

本次重构将 ScreenLockDetector 项目从平台条件编译的单一类结构重构为面向对象的继承体系,使用抽象基类和平台特定的子类实现。

重构目标

  1. 提高代码可维护性: 将平台特定代码分离到独立的类中
  2. 改善代码结构: 使用面向对象设计模式(工厂模式 + 模板方法模式)
  3. 增强可扩展性: 便于添加新平台支持
  4. 减少代码耦合: 消除大量的 #ifdef 条件编译

架构设计

类层次结构

ScreenLockDetectorBase (抽象基类)
    ├── ScreenLockDetectorLinux (Linux 实现)
    └── ScreenLockDetectorMacOS (macOS 实现)

ScreenLockDetector (工厂类)

设计模式

  1. 工厂模式: ScreenLockDetector 根据平台创建相应的检测器实例
  2. 模板方法模式: ScreenLockDetectorBase 定义通用接口,子类实现特定逻辑
  3. 策略模式: 不同平台的检测策略封装在各自的类中

文件结构

新增文件

文件名 说明
screenlockdetector_base.h 抽象基类头文件
screenlockdetector_base.cpp 抽象基类实现
screenlockdetector_linux.h Linux 子类头文件
screenlockdetector_linux.cpp Linux 子类实现
screenlockdetector_macos.h macOS 子类头文件
screenlockdetector_macos.mm macOS 子类实现 (Objective-C++)

修改文件

文件名 变更说明
screenlockdetector.h 从平台特定类改为工厂类
screenlockdetector.cpp 实现工厂方法,创建平台特定实例
CMakeLists.txt 更新源文件列表

弃用文件

文件名 说明
screenlockdetector_mac.h 已重命名为 screenlockdetector_macos.h
screenlockdetector_mac.mm 已重命名为 screenlockdetector_macos.mm

类详细说明

1. ScreenLockDetectorBase (抽象基类)

职责: 定义跨平台的公共接口和共享逻辑

主要成员:

  • bool isScreenLocked() const - 获取锁屏状态
  • virtual bool initialize() = 0 - 纯虚函数,由子类实现初始化
  • void setLockState(bool locked) - 受保护方法,供子类更新状态

信号:

  • void screenLocked() - 屏幕锁定信号
  • void screenUnlocked() - 屏幕解锁信号
  • void lockStateChanged(bool locked) - 状态变化信号

2. ScreenLockDetectorLinux (Linux 实现)

职责: 处理 Linux 平台的 DBus 信号监听

支持的桌面环境:

  • Deepin DDE
  • GNOME
  • KDE
  • XFCE
  • UKUI/KylinOS

实现细节:

  • 通过 QDBusInterface 连接到不同桌面环境的 DBus 服务
  • 监听 ActiveChangedVisiblelockunlock 等信号
  • 查询初始锁屏状态

3. ScreenLockDetectorMacOS (macOS 实现)

职责: 处理 macOS 平台的系统通知监听

实现细节:

  • 使用 NSDistributedNotificationCenter 监听系统通知
  • 监听的通知:
    • com.apple.screenIsLocked - 屏幕锁定
    • com.apple.screenIsUnlocked - 屏幕解锁
    • com.apple.screensaver.didstart - 屏保启动(可选)
    • com.apple.screensaver.didstop - 屏保停止(可选)
  • 使用 Objective-C 观察者模式

4. ScreenLockDetector (工厂类)

职责: 提供统一的接口,自动创建平台特定的检测器

实现方式:

ScreenLockDetectorBase* ScreenLockDetector::createPlatformDetector()
{
#ifdef Q_OS_MAC
    return new ScreenLockDetectorMacOS(this);
#elif defined(Q_OS_LINUX)
    return new ScreenLockDetectorLinux(this);
#else
    return nullptr;
#endif
}

使用方式:

// 创建检测器
ScreenLockDetector *detector = new ScreenLockDetector(this);

// 连接信号
connect(detector, &ScreenLockDetector::screenLocked,
        this, &YourClass::onScreenLocked);
connect(detector, &ScreenLockDetector::screenUnlocked,
        this, &YourClass::onScreenUnlocked);

// 初始化
if (!detector->initialize()) {
    qWarning() << "Failed to initialize screen lock detector";
}

重构优势

1. 代码分离

  • 之前: 所有平台代码混杂在一个文件中,充斥大量 #ifdef
  • 之后: 每个平台的代码独立成文件,清晰明了

2. 易于测试

  • 可以为每个平台创建独立的测试用例
  • 基类的通用逻辑可以单独测试

3. 便于扩展

添加新平台只需要:

  1. 创建继承自 ScreenLockDetectorBase 的新类
  2. 实现 initialize() 方法
  3. 在工厂方法中添加平台判断
  4. 更新 CMakeLists.txt

4. 降低耦合

  • 平台特定的头文件(如 QDBusNSDistributedNotificationCenter)只在对应的实现文件中引用
  • 主接口类不需要知道平台细节

5. 符合设计原则

  • 单一职责原则: 每个类只负责一个平台的实现
  • 开闭原则: 对扩展开放,对修改关闭
  • 依赖倒置原则: 依赖抽象而非具体实现

兼容性

本次重构完全兼容现有的外部接口:

  • ScreenLockDetector 类的公共接口保持不变
  • 信号定义保持不变
  • 使用方式保持不变

现有代码无需修改即可使用重构后的版本。

构建说明

Linux

mkdir build && cd build
cmake ..
make

macOS

mkdir build && cd build
cmake ..
make

CMake 会自动根据平台选择正确的源文件进行编译。

未来改进方向

  1. 添加 Windows 支持

    • 创建 ScreenLockDetectorWindows
    • 使用 WTSRegisterSessionNotification API
  2. 添加 Android/iOS 支持

    • 适用于 Qt for Mobile 应用
  3. 添加配置选项

    • 允许用户选择检测方式
    • 添加超时和重试机制
  4. 改进错误处理

    • 添加详细的错误码
    • 提供错误恢复机制
  5. 性能优化

    • 减少轮询(如果有)
    • 优化信号连接

测试建议

Linux 测试

  1. 在不同桌面环境下测试GNOME、KDE、Deepin、UKUI
  2. 测试锁屏/解锁事件
  3. 测试应用启动时的初始状态检测

macOS 测试

  1. 测试 Command+Control+Q 锁屏
  2. 测试屏保激活后的锁屏
  3. 测试从休眠恢复时的通知

作者

ScreenLockDetector 开发团队

版本历史

  • v2.0.0 (2025): 面向对象重构
  • v1.0.0 (2025): 初始版本