1. 功能介绍
Deskflow是一款免费且开源的键盘和鼠标共享应用程序,它允许你使用单个键盘和鼠标无缝控制多台计算机。类似于软件KVM(键盘、视频、鼠标)切换器,但不含视频组件,Deskflow让你可以将光标从一台屏幕边缘移出并进入另一台计算机的屏幕,键盘控制会自动跟随。
2. 整体架构与模块化设计
Deskflow采用客户端-服务器架构,物理设备接入端就是服务端。
3. 业务分层设计
Deskflow采用了清晰的分层架构设计:
| 应用层 | GUI应用程序和命令行工具 |
| 业务逻辑层 | 客户端/服务器核心逻辑,协议处理 |
| 服务层 | 网络通信、事件系统、配置管理 |
| 平台抽象层 | 操作系统接口抽象 |
| 基础设施层 | 日志、工具类、基础数据结构 |
4. 应用代码模块化
| 组件 | 描述 |
|---|---|
| deskflow-gui | 主图形用户界面 |
| deskflow-client | 接收输入事件的客户端应用程序 |
| deskflow-server | 发送输入事件的服务器应用程序 |
| deskflow-daemon | 用于系统集成的后台服务 |
| deskflow-core | 组件间共享的核心功能 |
5. 项目的核心库模块化
| lib模块 | 功能 |
|---|---|
| arch模块 | 操作系统抽象层,处理平台相关的底层操作 |
| base模块 | 基础设施模块,提供事件系统、日志、工具类等 |
| net模块 | 网络通信模块,负责TCP/SSL连接和数据传输 |
| platform模块 | 平台适配模块,处理不同操作系统的具体实现 |
| client/server模块 | 客户端和服务器核心逻辑 |
| deskflow模块 | 应用程序框架和配置管理 |
6. 软件设计思想
6.1. 抽象化
项目定义了一个基础接口类IInterface作为所有接口类的基类,所有接口类都只包含纯虚方法,每个接口类会提供多个派生类,分别适配不同操作系统。通过一个Arch单例类型整合了不同操作系统的系统调用。并基于此封装了IO、事件、网络、多线等等框架,所以业务层无需关心底层实现,直接调用封装好的框架即可。
6.2. 高内聚低耦合
高内聚
项目采用清晰的分层架构,将相关功能聚集在对应的模块中。每个库模块都专注于特定的功能领域,如 base 模块负责基础事件处理和日志功能,net 模块专门处理网络通信,platform 模块集中处理平台相关功能。平台特定的实现代码按操作系统进行分组,Windows、macOS、Linux 的相关代码分别聚集在对应的文件中,这种组织方式确保了同一平台的相关功能具有高内聚性。每个模块内部的功能高度相关,例如 base 模块集中了事件处理、日志记录、作业调度等核心基础功能。
低耦合
接口与实现完全分离
项目大量使用抽象接口,所有接口都继承自统一的基类 IInterface,这种设计确保了依赖抽象而非具体实现,实现了低耦合。以线程接口为例,通过IArchMultithread接口定义了跨平台的统一抽象,各平台的具体实现通过继承该接口来提供功能,核心业务逻辑与平台相关代码完全解耦,如果有需要可以优化/修改平台层代码而不影响业务层代码。
事件驱动的松耦合架构
系统采用事件队列机制实现组件间通信,通过 IEventQueue 接口定义事件处理能力。组件间通过事件进行异步交互,避免了直接依赖。
网络通信的抽象化
网络层通过 ISocket 等接口定义统一的网络通信抽象,将具体的 TCP、SSL 实现与上层业务逻辑解耦。
依赖注入
抽象基类 PlatformScreen 通过构造函数注入依赖,接受 IEventQueue* 参数,这也降低了组件间的耦合度。
6.3. 重用原则
模块化的库结构设计
项目采用了高度模块化的架构,将功能分解为多个独立的静态库,实现了代码的最大化重用。整个源码被组织成arch、base、client、common、deskflow、gui、io、mt、net、platform、server等多个库模块,每个库都有明确的职责边界,可以被多个应用程序重用。
接口抽象和继承体系
项目建立了完整的接口抽象体系,所有接口类都继承自统一的基础接口IInterface。这种设计确保了接口的一致性,使得不同的具体实现可以通过相同的接口被重用。
平台抽象层的重用设计
项目通过平台抽象层实现了跨平台的代码重用。例如,IPlatformScreen接口定义了平台无关的屏幕操作方法,而具体的实现则针对不同平台分别提供。构建系统根据目标平台自动选择相应的实现文件。
工厂模式的应用
客户端和服务端都使用工厂模式来创建平台特定的屏幕实现。ClientApp::createScreen()方法根据编译时的平台宏定义,创建相应的平台实现(如MSWindowsScreen、OSXScreen、XWindowsScreen或EiScreen)。服务端也采用了相同的模式。
共享组件的重用
项目中的核心组件如事件队列(EventQueue)、网络通信(TCPSocket)等被设计为可重用的共享组件。客户端和服务端应用程序都链接相同的基础库集合,实现了代码的高度重用。