从“写出来”到“交付出来”:归巢团队项目驱动的软件工程复盘

102300110尹肇兴 2025-12-25 18:26:49
这个作业属于哪个课程软件工程实践W班
这个作业要求在哪里作业要求链接
这个作业的目标回顾本学期软件工程实践课的学习与项目开发全过程,反思需求到发布各阶段的收获,总结个人技术成长,并结合项目思考软件开发模式的选择
其他参考文献《构建之法》

1| 软件工程实践——个人技术博客
2| 概述:
卫生评估用于宿舍卫生检查的“前后对比”:用户在小程序上传打扫前/后的两张图片,后端 Spring Boot 接收后转发给评估服务,再将返回的清洁度分数与指标解析为结构化结果或可读报告供前端展示。该技术适用于需要减少人工检查主观性、提高检查效率的场景,难点集中在跨端图片上传协议、评估结果的可解释性、以及外部评估服务的可配置与稳定联调。

写这篇技术复盘时,我刻意把重点放在“工程链路”而不是“算法玄学”上:我们真正踩坑的往往不是模型/特征怎么提,而是图片到底有没有传上来、Python 服务到底能不能连上、返回字段能不能稳定渲染、出了问题能不能快速定位

从“写出来”到“交付出来”:归巢团队项目驱动的软件工程复盘

0. 项目与我:一句话自我定位

这学期的软件工程实践课,我第一次在一个相对完整的团队项目里体验了“需求—设计—实现—测试—发布”的闭环。

  • 项目形态:微信小程序前端 + Spring Boot 3 后端(含 WebSocket、对象存储、数据库脚本、Dockerfile 等交付要素)。
  • 我的角色:以后端开发 + 文档为主,项目后期承担更多联调、异常与日志优化、最终测试与交付梳理。
  • 我最核心的产出方向:宿舍群聊(WebSocket/历史消息/多媒体上传)、卫生评估/卫生评分方向的分析与改造(对运行数据进行分析、指出不合理扣分点、推进参数配置化与新逻辑落地)、设备驱动抽象层与架构文档。

说明:本博客中的项目事实引用自仓库代码(例如后端 pom.xml/application.yml、数据库 db.sql、后端 Controller 代码、小程序 app.json/页面代码等)。

以下是我们的项目轮廓:

  • 前端形态:微信小程序(guichao/guichao),页面包含登录、清洁(AI 卫生检查)、群聊、设备、奖励、个人中心等(app.json 的 pages 列表可直接看到)。
  • 后端形态:Spring Boot 3(TeamPractice_GuiChao/TeamPractice_GuiChao),端口为 8081application.ymlDockerfile 一致)。
  • 核心依赖(后端)
    • Web:spring-boot-starter-web
    • 鉴权:Sa-Token
    • 数据层:MySQL + MyBatis-Plus
    • 实时通信:spring-boot-starter-websocket
    • 对象存储:MinIO(用于头像、聊天图片/语音等)
    • 其他能力:邮件/短信验证码、LangChain4j(AI 能力探索)
  • 数据库建模(db.sql)
    • 用户:sys_useruser_sign_in
    • 清洁任务/排班:taskdormitory_taskscheduleuser_schedule
    • 积分:reward_points
    • 群聊:chat_message
    • 设备:devicedevice_lightdevice_air_conditioner

这一段对我很重要:它让我在写文档/做联调时始终能对齐“系统边界”,避免在讨论中把一堆概念说得很大、但落不到实现。

1. 课程带给我的成长:从“会写功能”到“能对交付负责”

如果要总结我在这门课里最大的变化,我会用三个关键词:

  • 可验证:需求要能验收,问题要能复现,改动要能回归。
  • 可协作:结构要让队友容易对接,接口要稳定,异常要可读。
  • 可交付:环境、配置、数据库、部署脚本、版本边界都要能自洽。

过去写个人项目时,我经常把“跑通”当作完成;但在团队项目里,“跑通”只是开始,后面还有:

  • 让不同端(小程序/后端/外部服务)能稳定联动
  • 让别人能读懂、能修改
  • 让最后能部署、能复现

这些能力不是靠看书获得的,而是一次次联调失败、一次次需求返工、一次次线上环境差异带来的“被迫成长”。

更具体地说,我的成长不是“我又学了一个框架”,而是出现了几个明显的思维转变:

  • 我开始在写接口前先问:这个接口怎么被前端调用?要不要登录?失败时前端怎么提示用户?
  • 我开始在写功能后立刻补:最少需要哪些可复现条件(数据库表/初始化数据/配置项/端口)?
  • 我开始把“上线才发现”的问题,尽量提前变成“联调阶段就能暴露”的问题(例如把错误信息做得可读、把依赖地址抽成配置)。

2. 我曾深入思考的两个问题(含“我如何一步步厘清”)

问题一:需求到底应该写到什么粒度,才不会在联调时崩掉?

2.1 最初的困惑

我一开始对“需求文档”的理解偏向“功能列表”:有什么页面、有什么按钮、有什么接口。但很快我们在推进中遇到典型现象:

  • 同一个功能名,大家理解不同(例如“卫生评估”到底是只输出一个分数,还是要输出解释性报告?)
  • 开发能做,但验收没标准,最后只能靠主观

2.2 我如何一步步厘清

我在需求文档与联调中逐步形成了“可验证需求”的写法:

  • 把需求拆成可观测输入/输出
    • 以卫生评估为例:输入明确为“打扫前/后两张图片”;输出明确为结构化结果(小程序端展示 cleanliness_score/assessment_result/change_area_ratio)或一段可读报告。
  • 把边界条件写出来
    • 例如后端 EvaluationController 在图片为空时直接抛 IllegalArgumentException,这类行为应该在需求里作为“错误反馈方式”体现。
  • 把非功能要求写成“最小可交付标准”
    • 例如鉴权:项目采用 Sa-Tokenpom.xml 可见依赖),业务接口需要明确“是否要求登录”。群聊历史消息接口在代码中就做了 StpUtil.isLogin() 校验。

我在写需求说明书时还加了一条“对我最有用但很容易被忽视”的内容:

  • 把“验收动作”写成步骤:谁用什么账号,点到哪个页面,输入什么,看到什么算通过。

这让团队后期验收不再是“大家看着差不多”,而是能按步骤复现。

2.3 现在仍不完全明白的点

  • 当需求涉及算法(卫生评分)时,“公平性/解释性/鲁棒性”这些抽象词,如何写成可验收条款?
  • 当功能依赖外部服务(例如卫生评估依赖 localhost:5000/evaluate 的 Python 服务)时,需求里要不要写“不可用时的降级策略/超时策略/监控指标”?写多少算合适?

2.4 新产生的问题

  • 需求的变更不可避免,那么团队如何用最小成本管理需求版本?尤其是“算法逻辑”这种变更频繁、但影响面大的内容。

问题二:什么才算团队项目里的“好设计”?

2.5 最初的误区

以前我很容易把“优雅”当作好设计,比如模式多、抽象多;但团队项目里“好设计”的第一要义是:

  • 让协作成本低
  • 让变更成本可控

2.6 我从代码结构里学到的具体标准

我们后端的包结构天然在表达模块边界:

  • user:注册登录、验证码、用户信息、积分等(UserController
  • schedule:清洁任务、排班、用户日程(TaskController 等)
  • household:设备管理(DeviceController,以及 DeviceLight/DeviceAirConditioner 等实体)
  • websoket:宿舍群聊(历史消息、上传图片/语音,MinIO 存储)
  • cv:卫生评估(图片前后对比,调用 Python 服务)
  • config/common:Sa-Token、MinIO、WebSocket、统一异常等通用能力

对我来说,这种“模块化”本身就是团队协作的设计:你只要知道模块目录,就能快速找到接口入口、DTO/Entity、Service/Mapper。

同时,一些“工程化设计”也在代码里体现:

  • 可交付性Dockerfile 固定 Java 17 环境,暴露 8081db.sql 能一键初始化核心表。
  • 可维护性:统一异常类型(如 BadRequestException)使接口错误更可预期。

我对“好设计”的理解也在项目里被迫具体化。比如:

  • 群聊历史消息接口里,为了避免“前端误传宿舍导致串群”,后端会优先使用登录用户 session 中的宿舍信息(ChatMessageController 中有明确逻辑)。这看起来是一个很小的 if 判断,但背后其实是“用后端约束保证系统不被错误调用拖垮”。
  • 设备表采用“基础表 + 类型扩展表”(device + device_light/device_air_conditioner),这其实是在为未来设备类型扩展留接口,而不是把所有字段堆在一张超级大表里。

3. 五阶段复盘:需求/设计/实现/测试/发布

3.1 需求阶段:把“想要”写成“可验收”

  • 最大收获:需求不是“写给老师看”,而是写给团队的协作契约。
  • 我在项目里的实践:项目最开始我编写需求说明书,重点把“输入/输出/边界/验收”写清楚,尤其是跨端功能(卫生评估、群聊)需要严格定义协议。

这一阶段我踩过一个典型坑:

  • 我们最初写“卫生评估”时只写了“AI 检测卫生并评分”。后来联调时才发现:前端需要的是“结构化字段”用于页面表格,而不是后端拼接的一段长文本。于是我们才明确了“结构化输出(字段稳定)”与“解释性输出(文本报告)”的区分,并在后端保留了两种接口形态(/api/analyze/api/eval/upload)。

3.2 设计阶段:为协作、变更与联调做设计

  • 最大收获:设计的价值在于降低未来成本。
  • 我在项目里的实践
    • 接口设计尽量稳定,并统一异常语义。
    • 对“易变逻辑”(评分算法)考虑做参数化与抽象层,让逻辑迭代不至于把接口与数据结构一起推翻。

我在这一阶段学到的关键能力,是把“变化”当成常态:

  • 页面会改
  • 需求会改
  • 算法会改
  • 部署环境会跟本地不一样

如果设计一开始就把这些变化当作“不存在”,后面每次改动都会变成痛苦的重构。

3.3 实现阶段:把“工程质量”视作功能的一部分

pom.xmlapplication.yml 能看到我们实现阶段落地了很多工程化能力:

  • 鉴权:Sa-Token(sa-token-spring-boot3-starter
  • 数据库与 ORM:MySQL + MyBatis-Plus
  • 对象存储:MinIO(用于头像、群聊图片/语音等)
  • 实时通信:WebSocket(群聊)
  • 对外能力:短信/邮件验证码、以及 LangChain4j/OpenAI 的 AI 能力探索

我在实现阶段最大的收获不是写了多少代码,而是学会了把“系统风险点”提前显式化:

  • 外部依赖的地址、超时、失败提示
  • 存储与安全配置(例如 MinIO、短信/邮箱配置)
  • 统一错误处理与日志可观测

在这个过程中我也形成了一个固定习惯:

  • 每加一个外部依赖(短信、邮件、对象存储、Python 评估服务),我都会立刻问:
    • 地址/密钥在哪里配置?
    • 本地/部署环境怎么区分?
    • 失败时用户看到什么?
    • 出问题时我怎么定位?

这个习惯直接影响了我后续做异常处理与日志优化的效率。

3.4 测试阶段:测试是“降低交付风险”的工程手段

  • 最大收获:测试不只是写用例,更是把风险从“上线爆炸”前移到“联调发现”。
  • 我在项目里的实践:项目后期我完成用户界面的最终测试,整理 UI 组件文档,并推动“拆分→开发→联调→验收”的闭环。

我对测试的理解在这学期变得更工程化:

  • 测试不是“最后测一下”,而是“持续告诉我们:系统的哪一块现在最危险”。
  • 对跨端功能(例如图片上传、群聊、对象存储回显)来说,单元测试覆盖有限,更多需要的是:
    • 明确的联调脚本
    • 可复现的测试数据
    • 可读的错误信息

3.5 发布阶段:交付不仅是打包,更是可复现

发布阶段让我意识到:只要团队要交付,下面这些“非功能”就必须被当作必需品:

  • 可部署Dockerfile、端口(8081)、JAR 打包产物
  • 可初始化:数据库脚本 db.sql
  • 可配置application.yml(数据源、对象存储、邮件短信等)

否则项目很容易陷入“在我电脑上可以”的尴尬。

这一阶段我最大的收获,是第一次把“交付”当作一个系统工程:

  • 后端 Dockerfile 让部署环境可控(Java 17、端口暴露、JAR 入口)。
  • db.sql 让数据库初始化可复现(表结构清晰、字段含义明确)。
  • 但同时我也意识到:配置文件里往往会出现敏感信息(例如各类 key),这在真实项目里必须走环境变量/配置中心/密钥管理,而不是直接写进仓库。

4. 我在团队项目中的具体贡献(按模块/问题归类)

4.1 宿舍群聊:从“能聊”到“可用”

我在群聊方向关注的不是“发消息”这一件事,而是整个使用闭环:

  • 历史消息分页:后端 ChatMessageController 提供 /messages/history,并做了登录校验。
  • 宿舍隔离:接口优先使用当前登录用户的宿舍作为群聊标识,避免前端误传导致串群(代码中有明确处理)。
  • 多媒体上传/messages/uploadImage/messages/uploadAudio 统一上传到 MinIO,再返回 URL。

这类功能的工程点在于:

  • 权限与数据隔离
  • 分页与性能
  • 文件存储的一致性

如果把群聊功能拆成“对用户可感知的能力”,我会这么描述:

  • 能持续看见上下文:历史消息分页,不会一刷新就“聊天记录没了”。
  • 能安全地聊:必须登录,且按宿舍隔离。
  • 能发更多类型内容:图片/语音上传后能稳定回显(对象存储 URL)。

这几个点看起来都很“功能”,但它们背后其实分别对应:分页、权限隔离、对象存储与 URL 访问策略。

4.2 卫生评估/卫生评分:从“输出分数”到“解释与改进”

我在这个方向的工程思维是:

  • 评估系统必须给出“理由”,否则团队/用户无法信任
  • 算法是会变的,因此要追求“参数化、可实验、可回滚”

目前仓库中可直接引用的实现是 cv 模块:

  • 小程序清洁页面 pages/main/clean/clean.js 上传前后照片
  • 后端 ImageAnalysisController/EvaluationController 转发图片到 Python 服务 localhost:5000/evaluate 并解析结果
  • EvaluationReportGenerator 将细分指标转换为可读报告

我在卫生评估方向最深的体会是:

  • “评分”本身不是终点,真正的目标是减少争议、提升效率。
  • 如果系统只给一个分数,团队很难解释“为什么扣分”;而一旦解释不清,系统的信任会快速崩塌。

因此我倾向于把“解释层”当作算法系统的一部分:即使算法在 Python 端实现,我们也至少能在后端把返回结果组织成可读报告,并给出改进建议。

而你提到的“旧扣分逻辑修正、新评分算法、A/B 测试环境、参数配置化、数学模型”等更深内容,我需要进一步定位到对应代码/配置/文档后,才能在博客中逐段引用(见本文末尾“待补材料”)。

4.3 设备驱动抽象层:让设备类型扩展不至于改爆业务

从数据库 db.sql 可以看到设备表按“基础表 + 类型扩展表”建模:

  • device:通用字段(device_id、type、dormitory、status、power、is_online 等)
  • device_light:灯光扩展(brightness、color_temperature、mode 等)
  • device_air_conditioner:空调扩展(temperature、fan_speed、mode 等)

这种建模天然支持“抽象层 + 插件化扩展”的思路:新增设备类型时,不需要把所有设备逻辑都塞进一个巨大表/巨大类里。

对我而言,“抽象层”不是为了炫技,而是为了避免两种团队协作灾难:

  • 新增一种设备,就要改几十处 if-else
  • 新增一种设备,就要把数据库表推倒重来

5. 软件开发模式:轻量级任务驱动迭代的得失

5.1 我们采用的模式

我们采用的是轻量级任务驱动的迭代开发模式,不完全遵循 Scrum,但每个模块基本按以下闭环推进:

  • 拆分
  • 开发
  • 联调
  • 验收

5.2 优点:把风险分散到每一次迭代

  • 需求偏差更早暴露:联调时立刻发现接口/展示与预期不一致。
  • 功能可持续交付:每次都能形成一个能演示的增量,而不是最后堆在一起。

5.3 缺点:如果缺少“工程债”管理,迭代会变成返工

  • 迭代会天然引入临时方案:硬编码、无配置、无降级
  • 若不定期偿还工程债,后期会在联调与发布阶段集中爆雷

我个人的经验结论是:对于课程项目,轻量级迭代是最合适的;但必须配套:

  • 明确接口契约
  • 清晰模块边界
  • 持续联调
  • 最低限度的交付要素(Docker/db.sql/配置说明)

如果让我回到项目一开始重新选一次模式,我仍然会选“轻量级任务驱动迭代”,但我会更早引入两件事:

  • 对齐接口契约:每个模块开工前先把请求/响应字段写出来。
  • 每次迭代必须留痕:哪怕只是简单的变更记录与验收 checklist。

6. 七大课程目标自评(百分制 + 解释更细化)

评分口径:我是否能在项目中稳定做出对应成果,而不是是否“听懂”。

  • 目标1(职业道德/社会影响):80
    • 我能意识到卫生评估/评分这类功能会直接影响“公平感”,因此更强调解释性输出与可追溯;但对更系统的伦理与合规框架仍需继续学习。
  • 目标2(需求分析全过程):85
    • 在写需求说明书与联调过程中形成了“输入/输出/边界/验收”的写法;但对非功能需求(可用性、降级、监控)的表达仍需提升。
  • 目标3(全过程开发与设计原则):88
    • 通过模块划分(user/schedule/household/websocket/cv)与通用能力(鉴权、存储、WebSocket、异常)落地,理解了设计与实现如何协同。
  • 目标4(技术评测与评判能力):82
    • 我能做运行数据分析、定位不合理扣分点、提出修正方案;但更系统的评测体系(指标、实验设计、统计显著性)仍需加强。
  • 目标5(文档标准与工程表达):90
    • 我承担了需求说明书、UI 组件文档、交付梳理等工作,能用较规范的方式与队友对齐。
  • 目标6(团队协作与沟通):88
    • 在联调/验收阶段能推动闭环,但对冲突管理与节奏控制仍有提升空间。
  • 目标7(项目管理与估算):78
    • 能拆任务并推进迭代,但对规模估算、工期量化、风险缓冲的能力仍不够成熟。

7. 参考文献

  • 《构建之法》(邹欣)
...全文
65 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
该文档【可回收工业检测纳米机器人设计方案详解:表面催化自清洁涂层与自动归巢磁场导航】共计 515 页,共50个大章节,文档支持目录章节跳转同时还支持阅读器左侧书签大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。文档前20个章节内容:【纳米机器人在工业检测领域的技术突破与应用价值、表面催化自清洁涂层的核心作用与创新机制、自动归巢磁场导航系统的工作原理与优势、可回收设计理念在纳米机器人中的重要意义、工业检测环境对纳米机器人性能的特殊要求、纳米机器人材料选择的关键考量因素、表面催化自清洁涂层的材料配方与特性、磁场导航系统的磁场产生与感应技术、纳米机器人微纳加工制造的工艺流程、自清洁涂层的制备工艺与技术要点、磁场导航模块的集成与调试方法、纳米机器人运动控制算法的设计与优化、表面催化反应的动力学模型与分析、磁场导航路径规划的策略与实现、纳米机器人能源供应方案的比较与选择、自清洁涂层的耐久性与稳定性测试方法、磁场导航系统的精度与可靠性保障、纳米机器人表面功能化修饰的技术手段、催化涂层对不同污染物的降解效率研究、磁场导航在复杂工业环境中的适应性优化】。更多精品资源请访问 https://blog.csdn.net/ashyyyy/article/details/146464041

114

社区成员

发帖
与我相关
我的任务
社区描述
202501福大-软件工程实践-W班
软件工程团队开发结对编程 高校 福建省·福州市
社区管理员
  • 202501福大-软件工程实践-W班
  • 离离原上羊羊吃大草
  • MiraiZz2
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧