14 KiB
14 KiB
ScreenLockDetector 类图
UML 类图
┌─────────────────────────────────────────────────────────────┐
│ ScreenLockDetector │
│ (工厂类/门面类) │
├─────────────────────────────────────────────────────────────┤
│ - m_detector: ScreenLockDetectorBase* │
├─────────────────────────────────────────────────────────────┤
│ + ScreenLockDetector(parent: QObject*) │
│ + ~ScreenLockDetector() │
│ + initialize(): bool │
│ + isScreenLocked(): bool │
│ - createPlatformDetector(): ScreenLockDetectorBase* │
├─────────────────────────────────────────────────────────────┤
│ signals: │
│ + screenLocked() │
│ + screenUnlocked() │
│ + lockStateChanged(locked: bool) │
└─────────────────────────────────────────────────────────────┘
│
│ creates
▼
┌─────────────────────────────────────────────────────────────┐
│ ScreenLockDetectorBase (抽象基类) │
│ <<abstract>> │
├─────────────────────────────────────────────────────────────┤
│ - m_isLocked: bool │
├─────────────────────────────────────────────────────────────┤
│ + ScreenLockDetectorBase(parent: QObject*) │
│ + ~ScreenLockDetectorBase() │
│ + isScreenLocked(): bool │
│ + initialize(): bool = 0 <<pure virtual>> │
│ # setLockState(locked: bool) │
├─────────────────────────────────────────────────────────────┤
│ signals: │
│ + screenLocked() │
│ + screenUnlocked() │
│ + lockStateChanged(locked: bool) │
└─────────────────────────────────────────────────────────────┘
△
│
┌─────────────┴─────────────┐
│ │
│ │
┌───────────────────────────┐ ┌───────────────────────────┐
│ ScreenLockDetectorLinux │ │ ScreenLockDetectorMacOS │
├───────────────────────────┤ ├───────────────────────────┤
│ - m_gnomeInterface │ │ - m_observerToken │
│ - m_ukuiInterface │ │ - m_initialized │
│ - m_deepinInterface │ │ │
│ - m_gnomeConnected │ │ │
│ - m_ukuiConnected │ │ │
│ - m_deepinConnected │ │ │
├───────────────────────────┤ ├───────────────────────────┤
│ + initialize(): bool │ │ + initialize(): bool │
│ - connectToGnome...() │ │ + handleScreenLocked() │
│ - connectToUkui...() │ │ + handleScreenUnlocked() │
│ - connectToDeepinDDE() │ │ + handleScreenSaver...() │
│ - queryCurrentLockState() │ │ - registerNotification..()│
│ - getCurrentSessionPath() │ │ - unregisterNotification()│
├───────────────────────────┤ ├───────────────────────────┤
│ slots: │ │ (与 Obj-C 观察者交互) │
│ - onScreenSaverActive...()│ │ │
│ - onLockFrontVisible() │ │ │
│ - onSessionLocked() │ │ │
│ - onSessionUnlocked() │ │ │
└───────────────────────────┘ └───────────────────────────┘
│ │
│ uses │ uses
▼ ▼
┌───────────────────┐ ┌────────────────────────────┐
│ QDBusInterface │ │ NSDistributed │
│ QDBusConnection │ │ NotificationCenter │
│ (Qt DBus API) │ │ (Cocoa Framework) │
└───────────────────┘ └────────────────────────────┘
类关系说明
继承关系 (Inheritance)
ScreenLockDetectorLinux继承自ScreenLockDetectorBaseScreenLockDetectorMacOS继承自ScreenLockDetectorBaseScreenLockDetector继承自QObjectScreenLockDetectorBase继承自QObject
组合关系 (Composition)
ScreenLockDetector拥有一个ScreenLockDetectorBase*成员ScreenLockDetectorLinux拥有多个QDBusInterface*成员ScreenLockDetectorMacOS拥有一个void*(Objective-C 对象指针)
依赖关系 (Dependency)
ScreenLockDetectorLinux依赖 Qt DBus APIScreenLockDetectorMacOS依赖 Cocoa Framework API
设计模式
1. 工厂方法模式 (Factory Method Pattern)
ScreenLockDetectorBase* ScreenLockDetector::createPlatformDetector()
{
// 根据平台创建具体实例
#ifdef Q_OS_MAC
return new ScreenLockDetectorMacOS(this);
#elif defined(Q_OS_LINUX)
return new ScreenLockDetectorLinux(this);
#else
return nullptr;
#endif
}
优点:
- 客户端代码不需要知道具体创建哪个类
- 新增平台只需修改工厂方法
- 符合开闭原则
2. 模板方法模式 (Template Method Pattern)
// 基类定义算法骨架
class ScreenLockDetectorBase {
public:
virtual bool initialize() = 0; // 留给子类实现
protected:
void setLockState(bool locked); // 公共实现
};
// 子类实现具体步骤
class ScreenLockDetectorLinux : public ScreenLockDetectorBase {
public:
bool initialize() override {
// Linux 特定的初始化
connectToGnomeScreenSaver();
connectToDeepinDDE();
// ...
}
};
优点:
- 公共逻辑复用(setLockState)
- 平台特定逻辑分离(initialize)
- 易于维护和扩展
3. 门面模式 (Facade Pattern)
class ScreenLockDetector {
// 为客户端提供简单的接口
// 隐藏内部的平台检测复杂性
private:
ScreenLockDetectorBase *m_detector;
};
优点:
- 简化客户端使用
- 隐藏复杂的平台差异
- 提供统一的接口
时序图
初始化流程
客户端 ScreenLockDetector ScreenLockDetectorBase 平台实现类
│ │ │ │
│ new ScreenLockDetector() │ │ │
│──────────────────────────>│ │ │
│ │ │ │
│ initialize() │ │ │
│──────────────────────────>│ │ │
│ │ │ │
│ │ createPlatformDetector() │
│ │────────────────────────────────────────────>│
│ │ │ new │
│ │<────────────────────────────────────────────│
│ │ │ │
│ │ connect signals │ │
│ │─────────────────────>│ │
│ │ │ │
│ │ initialize() │ │
│ │──────────────────────┼────────────────────>│
│ │ │ connectToXXX() │
│ │ │<────────────────────│
│ │ │ │
│ │<─────────────────────┼─────────────────────│
│<──────────────────────────│ true │ │
│ │ │ │
锁屏事件流程
系统事件 平台实现类 ScreenLockDetectorBase ScreenLockDetector 客户端
│ │ │ │ │
│ Lock Event │ │ │ │
│────────────────────>│ │ │ │
│ │ │ │ │
│ │ setLockState(true)│ │ │
│ │───────────────────>│ │ │
│ │ │ emit lockStateChanged│ │
│ │ │─────────────────────>│ │
│ │ │ │ emit signal │
│ │ │ │──────────────>│
│ │ │ emit screenLocked │ │
│ │ │─────────────────────>│ │
│ │ │ │ emit signal │
│ │ │ │──────────────>│
│ │ │ │ │
扩展性示例
添加 Windows 平台支持
1. 创建新类:
ScreenLockDetectorWindows : public ScreenLockDetectorBase
2. 实现 initialize() 方法
3. 更新工厂方法:
ScreenLockDetector::createPlatformDetector()
{
#ifdef Q_OS_WIN
return new ScreenLockDetectorWindows(this);
#endif
}
4. 更新 CMakeLists.txt
类图更新后:
ScreenLockDetectorBase
△
│
┌────┴────┬──────────┬────────────┐
│ │ │ │
Linux macOS Windows Android
职责分配
| 类 | 职责 | 平台 |
|---|---|---|
ScreenLockDetector |
工厂类,创建平台实例,转发信号 | 所有 |
ScreenLockDetectorBase |
定义接口,管理公共状态 | 所有 |
ScreenLockDetectorLinux |
DBus 信号监听和处理 | Linux |
ScreenLockDetectorMacOS |
NSDistributedNotificationCenter 监听 | macOS |
优势总结
- 单一职责: 每个类只负责一个平台
- 开闭原则: 对扩展开放,对修改关闭
- 里氏替换: 子类可以替换基类使用
- 依赖倒置: 依赖抽象而非具体实现
- 接口隔离: 客户端只依赖需要的接口
参考
- Design Patterns: Elements of Reusable Object-Oriented Software (GoF)
- Qt Documentation: https://doc.qt.io/
- SOLID Principles