270 lines
14 KiB
Markdown
270 lines
14 KiB
Markdown
|
|
# 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` 继承自 `ScreenLockDetectorBase`
|
|||
|
|
- `ScreenLockDetectorMacOS` 继承自 `ScreenLockDetectorBase`
|
|||
|
|
- `ScreenLockDetector` 继承自 `QObject`
|
|||
|
|
- `ScreenLockDetectorBase` 继承自 `QObject`
|
|||
|
|
|
|||
|
|
### 组合关系 (Composition)
|
|||
|
|
- `ScreenLockDetector` 拥有一个 `ScreenLockDetectorBase*` 成员
|
|||
|
|
- `ScreenLockDetectorLinux` 拥有多个 `QDBusInterface*` 成员
|
|||
|
|
- `ScreenLockDetectorMacOS` 拥有一个 `void*` (Objective-C 对象指针)
|
|||
|
|
|
|||
|
|
### 依赖关系 (Dependency)
|
|||
|
|
- `ScreenLockDetectorLinux` 依赖 Qt DBus API
|
|||
|
|
- `ScreenLockDetectorMacOS` 依赖 Cocoa Framework API
|
|||
|
|
|
|||
|
|
## 设计模式
|
|||
|
|
|
|||
|
|
### 1. 工厂方法模式 (Factory Method Pattern)
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
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)
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
// 基类定义算法骨架
|
|||
|
|
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)
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
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 |
|
|||
|
|
|
|||
|
|
## 优势总结
|
|||
|
|
|
|||
|
|
1. **单一职责**: 每个类只负责一个平台
|
|||
|
|
2. **开闭原则**: 对扩展开放,对修改关闭
|
|||
|
|
3. **里氏替换**: 子类可以替换基类使用
|
|||
|
|
4. **依赖倒置**: 依赖抽象而非具体实现
|
|||
|
|
5. **接口隔离**: 客户端只依赖需要的接口
|
|||
|
|
|
|||
|
|
## 参考
|
|||
|
|
|
|||
|
|
- Design Patterns: Elements of Reusable Object-Oriented Software (GoF)
|
|||
|
|
- Qt Documentation: https://doc.qt.io/
|
|||
|
|
- SOLID Principles
|