现代软件工程-对编程项目总结作业2

现代软件工程-对编程项目总结作业2

  • 项目仓库地址:
    • Gitee:https://z.gitee.cn/zgca/repos/zgca/elevator_hw
    • GitHub:https://github.com/Shenzhaolong1330/elevator_hw

摘要

本项目实现了一个智能电梯调度系统,采用客户端-服务器架构,将“算法控制”和“GUI显示”完全解耦。系统支持作为独立客户端对接电梯模拟服务器,既可以运行本组算法配合本组界面,也可以跨组互相对接。核心算法基于分区驻守与 SCAN 顺扫策略,并使用评分派梯实现更高效的响应。项目附带完整的启动脚本与依赖说明,便于在 Windows/Linux 环境下运行。


目录结构

/repo_root
├── gui.py                  # 原始 GUI 组件库(监控系统主窗口、信号桥、事件回调)
├── gui_only.py             # 纯 GUI 模式(仅显示,不控制;观察者模式)
├── algorithm_only.py       # 纯算法模式(只控制,不显示;调度控制器)
├── start.bat               # Windows 启动脚本(按序启动 Server→GUI→Algorithm)
├── start.sh                # Linux 启动脚本(GUI模式)
├── start_no_gui.bat        # Windows 无头模式(仅算法)
├── start_no_gui.sh         # Linux 无头模式(仅算法)
├── requirements.txt        # 依赖包清单
├── README.md               # 项目使用与设计说明
└── result.json             # 状态快照(tick/elevators/events/passengers 等)

1. PSP 计划表(开发前估算)

说明:PSP(Personal Software Process)用于在编码前做时间预算与过程管理。以下是我们在开始实现程序前的时间估算。单位为小时。

阶段子项说明估算耗时实际耗时差异原因
规划计划明确目标、范围、角色分工22
需求分析场景与约束梳理电梯参数、事件模型、服务能力、接口边界23模拟器事件模型理解花费更多时间
高层设计架构设计信息隐藏、接口设计、松耦合方案、模块边界23接口边界拉齐与跨组对接讨论
详细设计算法与数据结构调度策略(SCAN + 分区 + 评分)、状态管理67评分函数维度调整与权重试验
编码模块实现algorithm_only / gui_only / gui88
单元测试测试用例事件回放、边界情况、能耗统计43测试没有预想中困难
集成测试GUI对接算法接口互通、状态同步43就绪标记与启动顺序等问题解决比较顺利
重构需求变更适配评分函数调整、状态机补强、异常处理44
文档README/博客使用说明、设计说明、对接说明11
代码评审Pair Review双人走查、规范统一22
发布打包与脚本start.bat / start_no_gui.bat / 环境变量方案33

2. 信息隐藏、接口设计、松耦合:我们是如何落地的

  • 信息隐藏(Information Hiding)

    • 算法控制器内部状态(unit_state、unit_heading、service_queue、pending_calls、zone_assignment、move_count、total_energy)全部封装在算法侧,不暴露给 GUI 或其他模块;外部仅通过电梯代理 API(ProxyElevator.go_to_floor)与事件回调(on_init/on_elevator_stopped 等)交互。
    • GUI 只负责可视化:SignalBridge 把控制器事件转换为界面信号;界面不依赖任何算法的内部实现细节。
  • 接口设计(Interface Design)

    • 基于 elevator_saga 的统一事件回调接口:on_init、on_passenger_call、on_elevator_move、on_elevator_stopped、on_elevator_idle、on_elevator_passing_floor、on_elevator_approaching、on_event_execute_start、on_event_execute_end。算法控制器 IntelligentDispatchController 只需实现这些接口即可对接模拟器。
    • 通过环境变量 ELEVATOR_CLIENT_TYPE 控制运行模式(gui / algorithm / server),实现“显示”与“控制”的解耦。
  • 松耦合(Loose Coupling)

    • GUI 与算法分别是独立客户端,连接 Elevator Server(elevator_saga 模拟器)。GUI 可以对接任意算法,算法也可对接任意 GUI。
    • 启动脚本采用顺序启动与“就绪标记”机制,避免耦合与竞争(先 Server,后 GUI,待 GUI 就绪再启动 Algorithm)。

3. 重要模块接口的设计与实现过程

算法控制器:IntelligentDispatchController(algorithm_only.py)

  • 入口 main()
    • 设置环境变量 ELEVATOR_CLIENT_TYPE=algorithm
    • 实例化控制器并启动(controller.start())
  • on_init(elevators, floors)
    • 初始化每台电梯状态(idle/none)
    • 计算“驻守楼层(home)”与“服务分区(zone)”
    • 电梯移动至驻守楼层(immediate=True)
  • on_passenger_call(passenger, floor, direction)
    • 将呼叫加入 pending_calls(up/down),触发智能派梯 _intelligent_dispatch(target_floor, direction)
  • _intelligent_dispatch(target_floor, direction)
    • 对所有电梯做评分(距离、方向一致、空闲优先、分区匹配、负载约束)
    • 选择评分最高者并执行 _assign_task(best_unit, target_floor)
  • _assign_task(unit, target_floor)
    • 将目标楼层加入该电梯 service_queue
    • 若电梯空闲(idle),立即执行 _execute_next
  • _execute_next(unit)
    • 使用 SCAN 顺扫策略:沿当前方向优先处理最近目标;若该方向无目标,则反向或回归队列首;最终调用 unit.go_to_floor(next_floor)
  • on_elevator_move(elevator, from_pos, to_pos, direction, status)
    • 统计移动次数与能耗(例如第 4 台电梯能耗权重更高)
  • on_elevator_stopped(elevator, floor)
    • 移除停靠楼层、清理 pending_calls
    • 若有队列或载客,继续执行 _execute_next;否则回 idle
  • on_elevator_idle(elevator)
    • 若仍有队列,继续执行
    • 否则从 pending_calls 中“抢最近呼叫”
    • 完全空闲则返回驻守楼层(immediate=True)

GUI 监控系统(gui_only.py / gui.py)

  • GUIOnlyController
    • 接收事件,不主动控制(观察者模式),避免触发模拟器重置
    • 通过 SignalBridge 发出日志与状态更新到界面
  • ElevatorMonitorSystem(QMainWindow)
    • 主窗口,包含电梯卡片栅格、日志面板、控制栏;持有 SignalBridge
    • start_simulation() 启动观察线程 run_simulation_observable
  • run_simulation_observable
    • 持续监听模拟器状态
    • 用 tick(模拟器时钟)与 last_elevator_states 检测刷新
    • 安全处理算法重启导致的 tick 回退,避免界面崩溃

4. 算法关键与独到之处

  • 分区与驻守:每台电梯初始化时分配服务区与驻守楼层,缩短响应距离,减少“全楼巡航”的无效移动。
  • SCAN 顺扫策略:沿既定方向优先处理离当前最近的目标,减少方向反复与不必要停靠,降低乘客等待时间。
  • 智能评分派梯:
    • 距离代价:越近越好
    • 方向一致性:不反向优先
    • 空闲优先:idle 电梯优先响应
    • 分区匹配:目标楼层在本电梯负责区更优
    • 负载约束:接近满员/接近重量上限时拒绝外部新呼叫
  • 能耗统计:记录每台电梯移动次数与总能耗,为后续调度优化提供依据
  • 与“公交车(bus)算法”的对比
    • bus:层层停靠,上下循环;正确但慢,产生大量无效停靠
    • 我们的方案:“按需停靠”,评分派梯+SCAN+分区;理论上总旅行时间、总停靠次数更低,在呼叫稀疏或分布较均匀的场景下优势明显

5. 当需求发生变化时的重构与回归测试

  • 需求变化
    • 初版派梯仅考虑“最短距离”,忽略方向与负载
    • 新需求加入“方向一致性”“分区优先级”“能耗统计”
  • 重构策略
    • 拆分评分函数各维度并权重化
    • 补充 pending_calls 与 idle 回流策略
    • 统一在停靠事件中清理队列与 pending_calls,收敛状态管理
    • GUI 观察模式修复:避免触发 reset,采用 run_simulation_observable 持续监听
  • 回归测试
    • 固定 rush hour 场景进行事件回放,比对各版本总旅行时间与停靠次数
    • 使用 result.json 记录关键 tick 的状态快照(队列、方向、载客数)
    • 纯算法模式(start_no_gui.bat)进行速度回归
  • PR/MR 流程(Gitee/GitHub)
    • 采用 feature 分支 → PR → Review → squash merge
    • 冲突与解决:由于其中之一并不熟悉 git 的使用流程,在结对编程的前期一直是一位在 commit,后期两个人在 commit 的时候会先同步 repo 再进行 commit ,所以没有冲突与合并

6. 程序的代码规范与设计规范、异常处理、质量保障

  • 代码规范
    • PEP 8 命名、模块拆分清晰;函数关注单一职责
    • 日志统一通过 _emit_log 与 SignalBridge 输出,避免散乱打印
    • 脚本中使用 UTF-8(chcp 65001)避免中文乱码;路径使用带引号的变量,规避 Windows start 命令的坑
  • 异常处理
    • GUI 观察模式对状态获取做 try/except 与“强制刷新间隔”保护;算法重启导致的 tick 回退不会让 UI 崩溃
    • 启动脚本对 Python/conda 环境做显式检查与失败提示
  • 质量保障工具
    • 建议集成 flake8 + black + isort;CI 上跑单元测试与场景回归
  • 依赖(requirements.txt)
    flask>=2.0.0
    flask-cors>=3.0.0
    requests>=2.0.0
    elevator_saga>=0.1.0
    PyQt6>=6.5
    
    注:GUI 使用 PyQt6,请在环境中安装;Server/Client 通过 elevator_saga 连接电梯模拟服务器

7. 界面模块的详细设计与对接(MVC)

  • 设计目标:清晰展示多台电梯的运行状态(楼层/方向/载客/能耗)、呼叫信号与统计数据;与算法分离,支持跨组对接
  • 主要类与职责
    • ElevatorMonitorSystem(QMainWindow):主窗口;电梯卡片栅格、日志面板、控制栏;持有 SignalBridge
    • GUIOnlyController:连接模拟器,作为观察者接收事件;通过 signals(log_message 等)传递到 UI
    • SignalBridge:抽象信号通道,降低 UI 与 Controller 的耦合
  • 对接关系
    • 环境变量 ELEVATOR_CLIENT_TYPE=gui:仅显示
    • ELEVATOR_CLIENT_TYPE=algorithm:仅控制
    • ELEVATOR_CLIENT_TYPE=server:启动模拟器
    • GUI 启动后写入就绪标记,脚本等待就绪再启动算法,避免“边启动边重置”的竞争
  • MVC 实践参考(模型-视图-控制器)
    • Model:Elevator Server 状态(电梯/楼层/乘客)
    • View:PyQt6 卡片/日志/统计 UI
    • Controller:GUIOnlyController 与 Algorithm Controller
  • 截图展示
    在这里插入图片描述

8. 结对的过程与照片

  • 结对照片
    在这里插入图片描述

  • 采用的合作方式

    • 混合“Driver-Navigator”与“Ping-Pong Pairing”
    • Driver 专注编码实现;Navigator 监督方向与风险,查阅资料
    • Ping-Pong:一人写测试/用例,另一人完善实现,随后角色交换
  • 结对编程优缺点

    • 优点:实时评审减少缺陷;知识流动更快;复杂设计更易落地
    • 缺点:时间协调成本高;节奏不合容易疲劳;水平差异导致沟通成本上升
  • 伙伴优缺点

    • 优点:1. 相应迅速;2. 擅长vibe coding;3. 沟通顺畅
    • 缺点:过度关注微优化,影响迭代速度
  • 三明治方法的结构化反馈

    • 肯定贡献 → 指出具体问题与影响 → 提供可执行的改进建议

9. 其它收获与讨论

  • 攻克技术难点
    • 事件驱动与状态机复杂度:将“评分派梯”与“队列执行”分离,采用 SCAN 控制方向与停靠;pending_calls 统一收口外部呼叫,避免在事件回调中直接“拍脑袋”改队列
    • 跨组对接与启动顺序:用就绪标记等待 GUI 再启动算法,避免模拟器 reset 导致 tick 回退
  • 与 AI 工具配合
    • AI 做“第三方参与者”:用于资料检索、API 差异比对、测试数据生成;Navigator 对 AI 建议二次筛选,防止“合理但错误”的结论进入关键路径
  • 阅读与探索
    • 参考 elevator_saga 与 elevator-py 的接口文档;学习 MVC 在事件驱动 GUI 场景的应用(参考上文链接)
  • 若参与 KPI 比赛(总旅行时间等)
    • 优势:分区 + SCAN + 评分派梯可在热点楼层加速响应;能耗统计可用于调度细化(高能耗梯少跑长距离)
    • 劣势:呼叫极度集中且频繁反向时,SCAN 需要更精细的队列管理(例如并列目标的批处理与合并停靠)
  • 角色切换频率的平衡
    • 建议 25–40 分钟或“完成一个可度量子任务”为一轮;避免上下文丢失;轮换时由 Navigator 做简短交接
  • 结构化反馈促进团队成长
    • 对基础差异较大的伙伴,预设“任务包粒度”:强项者搭建骨架,弱项者补齐单元测试与边界情况;定期三明治反馈,记录改进点并度量(commit 数、测试覆盖、线上缺陷数)

10. 运行与对接说明

  • 纯 GUI 模式(观察者)
    • Windows:双击 start.bat(按序启动 Server→GUI→Algorithm)
    • 跨组对接:也可先启动其他组的算法,再运行本组 gui_only.py 并设 ELEVATOR_CLIENT_TYPE=gui
  • 纯算法模式(无头)
    • Windows:运行 start_no_gui.bat(内部设置 ELEVATOR_CLIENT_TYPE=algorithm 并启动 algorithm_only.py)
  • 环境变量与依赖
    • Python ≥ 3.8;pip 安装 requirements.txt
    • 环境变量 ELEVATOR_CLIENT_TYPE 控制运行模式:server / gui / algorithm
  • 兼容与注意
    • Windows CMD 中文需 chcp 65001;start 命令路径必须加引号;脚本使用 ^& 链接命令避免路径解析错误
    • 若使用 conda,脚本自动尝试激活指定环境;否则使用系统 Python
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值