一个大型项目(例如 自动化设备控制系统 / Qt + 嵌入式设备软件 )是如何 从最初设计 → 实施 → 遇到问题 → 重构 → 最终形成成熟架构 的。
整个过程会完全按照真实工程师的思考过程来讲,而不是直接给一个"完美架构"。
假设我们开发一个 自动化检测设备软件,设备包含:
- 电机(移动平台)
- 相机(拍照检测)
- 温度传感器
- TCP通信
- UI操作界面
一、阶段1:最初期设计(简单实现)
项目刚开始时,需求很简单:
需求:
1 启动设备
2 控制电机移动
3 拍照
4 显示温度
工程师通常会先写一个简单结构:
project
├── main.cpp
├── MainWindow.cpp
├── Motor.cpp
├── Camera.cpp
└── Sensor.cpp
代码示例
UI直接调用设备:
cpp
class MainWindow
{
public:
void startMotor()
{
motor.start();
}
void takePhoto()
{
camera.capture();
}
void showTemp()
{
double t = sensor.read();
}
private:
Motor motor;
Camera camera;
Sensor sensor;
};
设备类:
cpp
class Motor
{
public:
void start()
{
writeRegister(0x01,1);
}
};
优点
开发快
代码简单
问题很快出现
随着需求增加:
1 支持远程控制
2 加入电机速度控制
3 加入自动检测流程
4 加入日志
代码开始变成:
cpp
MainWindow
{
Motor motor;
Camera camera;
Sensor sensor;
TcpServer tcp;
}
UI里全是逻辑:
cpp
void MainWindow::onStartClicked()
{
motor.start();
tcp.send("motor started");
}
二、阶段2:第一次重构(Controller)
工程师发现问题:
❌ UI代码太复杂
❌ 逻辑到处都是
❌ UI直接控制硬件
于是进行第一次重构。
引入:
Controller
新结构
project
├── ui
│ └── MainWindow
│
├── controller
│ ├── MotorController
│ ├── CameraController
│ └── SensorController
│
└── driver
├── MotorDriver
├── CameraDriver
└── SensorDriver
UI变简单
cpp
void MainWindow::onStartClicked()
{
motorController.start();
}
Controller
cpp
class MotorController
{
public:
void start()
{
driver.enable();
}
private:
MotorDriver driver;
};
Driver
cpp
class MotorDriver
{
public:
void enable()
{
writeRegister(0x01,1);
}
};
调用流程
UI
↓
Controller
↓
Driver
↓
Hardware
三、阶段3:增加算法(Algorithm)
项目继续发展:
新需求:
1 电机需要PID控制
2 需要轨迹规划
3 需要图像处理
Controller开始变复杂:
cpp
class MotorController
{
public:
void update()
{
double error = target-pos;
double output = pid.update(error);
driver.setPWM(output);
}
};
工程师发现:
❌ 算法和控制逻辑混在一起
于是进行第二次重构。
引入 Algorithm 层
新结构:
project
├── controller
├── algorithm
└── driver
Algorithm
cpp
class PID
{
public:
double update(double error)
{
return kp*error + ki*sum + kd*diff;
}
};
Controller
cpp
class MotorController
{
public:
void update()
{
double error = target-pos;
double out = pid.update(error);
driver.setPWM(out);
}
private:
PID pid;
MotorDriver driver;
};
好处
算法可以独立测试:
cpp
PID pid;
double result = pid.update(0.5);
不需要设备。
四、阶段4:加入通信系统
新需求:
远程控制设备
需要:
TCP
串口
工程师开始写:
cpp
TcpServer
SerialPort
但很快发现问题:
❌ 通信代码混乱
❌ 不同协议混在一起
五、第三次重构(Protocol + Media)
通信系统通常拆成两层:
Protocol
Media
Media(通信通道)
负责传输:
TCP
Serial
CAN
示例:
cpp
class TcpServer
{
public:
QByteArray receive();
};
Protocol(协议解析)
解析数据:
SET_SPEED 1000
START
STOP
cpp
class DeviceProtocol
{
public:
Command parse(QByteArray data);
};
Controller执行命令
cpp
Command cmd = protocol.parse(data);
if(cmd.type == SET_SPEED)
{
motorController.setSpeed(cmd.value);
}
调用流程
TCP
↓
Media
↓
Protocol
↓
Controller
六、阶段5:系统越来越复杂
设备增加:
电机
相机
温度
网络
日志
配置
模块越来越多:
MotorController
CameraController
SensorController
工程师开始问:
这些模块谁来管理?
谁负责初始化?
谁负责启动?
七、第四次重构(Manager)
于是出现:
Manager
Manager负责:
初始化
生命周期
资源管理
SystemManager
cpp
class SystemManager
{
public:
void init()
{
motorController.init();
cameraController.init();
networkService.init();
}
};
程序启动
main
↓
SystemManager
↓
初始化所有模块
八、阶段6:UI越来越复杂
UI需要做很多事情:
控制设备
显示数据
远程操作
如果UI直接调用Controller:
UI → Controller
UI会变复杂。
九、第五次重构(Service)
于是加入:
Service
Service给UI提供接口。
DeviceService
cpp
class DeviceService
{
public:
void startMotor()
{
motorController.start();
}
double getTemperature()
{
return sensorController.readTemp();
}
};
UI
cpp
void MainWindow::onStartClicked()
{
deviceService.startMotor();
}
UI不用知道:
MotorController
MotorDriver
十、最终成熟架构
经过多次重构后,系统变成:
project
├── ui
├── service
├── manager
├── controller
├── algorithm
├── protocol
├── media
├── driver
├── thread
└── tools
系统层级:
UI
↓
Service
↓
Manager
↓
Controller
↓
Algorithm
↓
Driver
↓
Hardware
十一、完整实例流程
用户点击:
开始检测
流程:
UI
↓
DeviceService
↓
InspectionController
↓
MotorController
↓
PID
↓
MotorDriver
↓
Motor
拍照:
UI
↓
DeviceService
↓
CameraController
↓
CameraDriver
↓
Camera
远程命令:
TCP
↓
Media
↓
Protocol
↓
Controller
十二、工程师的真实思维过程
真实开发过程:
第一版
UI直接控制设备
↓
第二版
加入Controller
↓
第三版
加入Algorithm
↓
第四版
加入Protocol
↓
第五版
加入Manager
↓
第六版
加入Service
最终形成完整架构。
十三、一句话总结
大型软件架构其实是 不断重构演化出来的:
简单代码
↓
模块化
↓
分层
↓
服务化
↓
完整架构