《现代软件工程》结对编程项目总结
Published:
项目地址: https://z.gitee.cn/maoyigemax/elevator_scheduler.git
伙伴博客:https://www.yiges.site/Domain/Ark/Course/2025-10-27-se-pair-programming/
项目总结(稳定优先!!!)
我主要负责算法部分的设计和实现。原本以为算法实现会比较简单,初版使用了Vibe Coding工具做了一个类似量化的因子算法,简单修改,测试比较简单,并没有发现太大问题。然而在正式线下结对编程的时候,我根据要求生成了很多测试用例,效果很差,甚至有0到达的情况,然后意识到对于电梯算法来说稳定性和鲁棒性是基础中的基础,在经过长时间在原算法上改进之后,反而变得非常复杂,而且也不可靠,充分说明了大语言模型的幻觉问题。最后我们决定重新设计一个基于经典调度算法的方案,基于最可靠稳定的公交车算法一步步优化,最终实现了一个还不错的版本,虽然还不够完美,还有可优化的空间,而且要越完美反而越难,提升一点点性能有点牵一发而动全身的感觉,由于时间和精力有限,最终还是选择了一个折中的方案。
PSP 表格
| PSP 阶段 | 预估时间(分钟) | 实际记录(分钟) |
|---|---|---|
| 计划:明确需求和其他因素,估计以下的各个任务需要多少时间 | 45 | 45 |
| 开发(包括下面 8 项子任务) | 460 | 940 |
| ・ 需求分析(包括学习新技术、新工具的时间) | 30 | 30 |
| ・ 生成设计文档(整体框架的设计、各模块的接口、用时序图、快速原型等方法) | 30 | 30 |
| ・ 设计复审(和同事审核设计文档,或者自己复审) | 30 | 30 |
| ・ 代码规范(为目前的开发制定或选择合适的规范) | 20 | 20 |
| ・ 具体设计(用伪代码、流程图等方法来设计具体模块) | 20 | 20 |
| ・ 具体编码 | 240 | 540 |
| ・ 代码复审 | 60 | 60 |
| ・ 测试(自测测试、修改代码、提交修改) | 60 | 240 |
| 报告 | 130 | 130 |
| ・ 测试报告(发现了多少 bug,修复了多少) | 60 | 60 |
| ・ 计算工作量(多少行代码、多少次提交、多少测试用例、其他工作量) | 10 | 10 |
| ・ 事后总结,并提出改进计划(包括写文档、博客的时间) | 60 | 60 |
| 总共花费的时间(分钟) | 635 | 1115 |
Q & A
重要模块接口的设计与实现过程
前端设计
最初的版本我们都做了react架构前端,毛一戈同学的界面设计更精美,而且利用websocket实现了前后端通信,我的版本相对简单一些,后来我们决定采用毛一戈同学的版本作为最终的前端界面。具体设计可参考伙伴博客:https://www.yiges.site/Domain/Ark/Course/2025-10-27-se-pair-programming/#31
后端架构设计
🛰️ 前端通信机制
核心组件
- BaseControllerWithComm 类:继承自基础控制器 BaseController
- 通信协议:采用 WebSocket 实现前后端实时通信
技术优势
- ✅ 功能解耦:将通信功能独立封装,后续业务类专注于算法实现
- ✅ 性能优越:WebSocket 相比传统 HTTP 协议具有更低的延迟和更高的实时性
⚙️ 后端算法实现
核心控制器
EnergyEfficientScanningController(BaseControllerWithComm)
实现电梯调度算法的核心业务逻辑
🎯 智能角色管理
架构设计
- 主力机:处理日常大部分请求,能耗较低
- 备用机:能耗较高,在主力机满载时自动启用
设计优势
- ✅ 职责分明:直观的电梯分工策略
- 🔄 扩展性强:为后续优化算法预留了改进空间
👥 高效乘客跟踪系统
数据结构
使用字典队列维护乘客信息
性能优势
- ✅ 高效查询:支持 O(1) 时间复杂度的乘客状态更新
- ✅ 资源优化:相比请求类属性管理方式,内存使用更高效
🔄 核心调度算法
算法基础
以经典的扫描算法(SCAN) 为基石,集成智能优化策略:
优化策略
- 满载跳过:电梯满载时跳过沿途请求
- 空站跳过:无乘客上下时跳过停靠
- 智能转向:当前方向无任务时自动转向(双向无任务则原地待命)
- 意图导向:基于距离和乘客目标楼层智能决策运行方向
- 负载均衡:优先调度能耗更低的主力机
设计理念
- ✅ 稳定可靠:在成熟算法基础上渐进式优化
- ✅ 功能完备:确保电梯基础功能的稳定运行
- ✅ 效率优先:通过多维度策略提升整体运行效率
需求发生变化时,如何重构代码?如何用回归测试保证改动不影响原来的算法?
我们的需求从一开始的效率优先,变成了稳定性优先,然后在稳定性基础上提升效率,为此完全放弃了之前的算法实现,但是保留了代码结构和接口设计,没有影响到前端和通信模块。为了保证改动不影响原来的算法,我们编写了大量的测试用例,尽可能覆盖了各种边界情况和异常情况,确保每次修改后都能通过所有测试用例,从而保证代码的正确性和稳定性。
git版本控制相关
gitee一共进行了39次提交,github进行了35次(后续开发移植到gitee来实现)。没有采用pull request的方式,因为是结对编程,在本地维护个人分支,远程只保留主分支即可。我负责算法实现,所以毛一戈同学需要的merge操作会比较多。
程序的代码规范,设计规范
我们之间没有明确的代码规范,但是在编码过程中遵循了一些基本的规范,比如命名规范、注释规范、代码结构规范等。设计规范方面,我们采用了模块化设计,将不同的功能模块分离,便于维护和扩展。
描述结对的过程

找了个会议室从下午一直到晚上,期间有休息和吃饭时间。本来感觉是个很简单的问题,但是实际开发过程中遇到了很多问题,尤其是在算法设计和实现方面,花了大量时间进行调试和优化。结对过程中,经过与AI 工具的不断battle,最终在保证稳定性的基础上,设计出了一个还不错的电梯调度算法。
采用了哪种合作方式,以及结对编程的优点和缺点
我感觉应该是同行评审模式(Peer Review),主要也是负责不同的模块,但是会互相交流哪里可以改进。优点是可以互相学习,发现对方代码中的问题,提升代码质量;缺点是可能缺乏大局观。
PSP表格分析
从PSP表格中可以看出,实际开发时间远远超过了预估时间,主要原因是需求变化导致的重构和测试时间增加。尤其是在测试阶段,实际花费的时间是预估的4倍多,说明测试工作的重要性和复杂性。未来在项目计划阶段需要更加详细地考虑可能的需求变化和测试工作,以提高时间估计的准确性。
收获
AI工具的使用经验
AI在直接灌输任务文档的情况下,在完成相对需要保证稳定性的任务时,表现并不理想,尤其是在算法设计和实现方面,容易出现幻觉和无法处理边界情况的问题,所以需要一个经过验证的base方案,然后一步步优化提升,而不是完全依赖AI生成代码。
Leave a Comment