[I.3] 个人作业:结课总结
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 2026年春季软件工程 - 北京航空航天大学 |
| 这个作业的要求在哪里 | 课程个人总结作业 |
| 我在这个课程的目标是 | 通过个人项目、结对编程和团队项目,体验软件工程从需求到维护的完整流程,形成更工程化的开发思维。 |
| 这个作业在哪个具体方面帮助我实现目标 | 回顾自己在课程开始时提出的问题,并结合后续实践重新理解软件工程中的方法、协作和取舍。 |
以前提问题的博客链接:I.1 个人作业:阅读与提问
一、对曾经提出的问题的回答
在课程刚开始阅读教材时,我提出了八个问题。现在回头看,这些问题大多不是可以被一句话“标准答案”解决的问题,而是软件工程中反复出现的权衡题。它们真正的答案不是某个概念本身,而是在实践中逐渐形成的判断框架。
1. 如何避免“过早扩大化”,又保持可扩展性?
我现在的理解是:可扩展性不是提前设计一个庞大的抽象体系,而是在当前需求范围内,尽量降低未来修改的成本。
在结对编程的花见小路项目中,我们一开始也遇到过类似问题。比如 T1 只是做胜负判定,看起来可以直接写一串 if-else;但是考虑到 T2/T3 还要复用规则,我们没有把每个角色的分值和判定规则写死在分支里,而是使用了 scoreWeights = [2, 2, 2, 3, 3, 4, 5] 这样的表驱动方式,并把第三轮同分比较提取成辅助函数。这个抽象很小,但确实服务于后续需求。
团队项目 HexaVigil 中,这个问题被放大了很多。它不是一个简单功能,而是一个 Godot 肉鸽塔防游戏:九天三幕循环,白天探索、基建、事件和招募,夜晚进入塔防战斗,战后再进入遗物三选一和周期推进。如果一开始就试图做一个“万物皆可配置”的通用游戏框架,很容易陷入我在作业一中担心的“画扇面”;但如果把所有数值、单位、敌人、建筑和事件都写死在脚本里,后期平衡和扩展又会完全动不了。
我们最后采用的是“有限数据驱动”:units.json、enemies.json、buildings.json、buffs.json、events.json、wave_templates.json、night_affixes.json 等配置表负责数值和内容,程序脚本负责稳定规则。这样既没有抽象成脱离项目需求的通用引擎,又让新增干员、敌人、建筑、夜晚词缀和随机事件不必大面积改代码。这个实践让我更明确地理解了:好的扩展性不是“什么都能扩展”,而是把项目中最可能变化的部分放到正确的位置。
通过这次实践,我对“不要过早扩大化”的理解变得更具体:如果一个抽象只是为了想象中的宏大未来,而不能减少当前或下一轮迭代中的真实复杂度,那它很可能就是过早设计;如果一个抽象能把稳定规则和易变输入隔离开,并且不会显著增加理解成本,那它就是合理的工程冗余。
我给自己的判断标准是:
- 当前是否已经出现了至少两处相似逻辑,或者下一阶段需求已经明确会复用这部分逻辑;
- 抽象后是否让测试更容易写,而不是更难写;
- 新增的结构是否能用一句话讲清楚职责;
- 如果明天删掉这个抽象,是否只是少了“优雅”,还是会真实增加修改风险。
2. 当领航员无事可做时,结对编程还有效吗?
结对项目结束后,我对这个问题的看法发生了变化。领航员并不是只有在驾驶员写复杂代码时才有价值。很多时候,领航员真正做的是“实时质量控制”。
在花见小路项目里,T1 的逻辑并不算特别复杂,但很容易出现判定顺序错误。比如应该先判断 11 分立即胜利,再判断 4 枚胜利,最后才进入第三轮结算。如果驾驶员只关注把代码写出来,很容易因为“这段看起来也能跑”而忽略规则顺序。领航员拿着题面逐条对照,就能在错误还没有沉淀进代码前发现它。
但我也不再认为所有任务都必须强行结对。更合理的方式是“动态结对”:对规则复杂、影响面大、接口设计、重构、疑难 Bug、测试策略设计等任务进行结对;对机械性的代码搬运、简单样式调整、文档格式整理等任务,可以独立完成后再 review。
所以我现在对“复杂度阈值”的回答是:这个阈值不只由代码难度决定,还由任务风险决定。一个任务即使代码很短,只要它处在核心路径、容易引发连锁错误、或者团队成员理解不一致,就值得结对。
3. 敏捷中的“欢迎变化”和“保持节奏”如何平衡?
我现在认为,这两者并不矛盾。敏捷欢迎变化,指的是欢迎把变化纳入可管理的流程,而不是随时打断团队正在做的事情。
在课程项目中,需求变化几乎不可避免。个人项目中,我更关注自己能不能把题目要求做完;到了结对和团队项目,才发现真正难的是:当新想法、新问题、新限制出现时,怎样不让所有人同时陷入混乱。
HexaVigil 的开发过程尤其能体现这一点。项目从地图生成、迷雾探索、白天行动力、建筑系统、干员部署、敌人寻路、Boss、随机事件、遗物、UI 到宣传片,天然就会不断产生新想法。如果每一个新想法都立刻插进当前迭代,团队会很快失去节奏。因此我们需要把“玩法目标”压成稳定主线:先保证九天三幕的核心循环能跑通,再逐步扩展随机事件、夜晚词缀、遗物和 UI 表现。
文档在这里起了很大作用。玩法循环与模块分工 把白天运营、夜间战斗、肉鸽结算和模块职责写清楚;ARCHITECTURE.md 约束模块边界;INTERFACE.md 规定公开方法和 EventBus 信号;DATA_SCHEMA.md 约束配置表字段。需求变化并不是不能进来,而是要先判断它影响的是玩法循环、模块接口、数据表,还是单纯数值调整。不同类型的变化进入不同位置,团队才不会被“变化”本身拖垮。
我的理解是:Sprint 中途不是绝对不能变,而是需要区分“变更的紧急程度”和“变更的代价”。
- 如果变更影响用户核心价值,或者当前实现继续做下去会明显浪费大量时间,可以打断当前计划,但要重新评估范围,而不是简单加任务;
- 如果变更只是体验优化、锦上添花或想法尚不成熟,应进入 backlog,等下个迭代统一排序;
- 如果变更来自需求理解错误,团队应该优先修正,因为继续开发错误需求本身就是更大的浪费;
- 如果变更只是临时灵感,就不应该用“敏捷”之名破坏团队节奏。
因此,“欢迎变化”的前提是有边界、有评估、有取舍。敏捷不是随叫随到,而是用更短的反馈周期减少走偏。
4. 如何判断用户调研得到的是真实需求,而不是新的偏见?
作业二中我分析网易云音乐时,对这个问题有了更直接的体会。我一开始作为网易云老用户,很容易从自己的使用习惯出发,认为“推荐算法”“评论区文化”“独立音乐生态”就是它最核心的价值。但在采访同学时,我发现对方更在意工作学习时的沉浸感、白噪音和后摇推荐,而不是我非常看重的说唱社区氛围。
这让我意识到,用户调研不是为了证明自己的判断正确,而是为了暴露自己的盲区。所谓真实需求,往往不能只靠用户说了什么,也不能只靠观察者解释了什么,而要把访谈、观察、行为数据和原型验证结合起来。
我现在会用三层方式理解需求:
- 用户说出口的需求:例如“我想要推荐更准”;
- 用户行为暴露的需求:例如频繁跳过某类歌曲、反复打开某个歌单;
- 用户没有直接说出的深层需求:例如想要减少选择成本、获得陪伴感或保持学习状态。
为了减少偏见,不能只访谈和自己相似的人,也不能把单个用户故事直接上升为普遍结论。更可靠的方法是先形成假设,再用更多样本、原型测试或数据验证来筛掉自嗨式结论。
5. 当风险来自团队内部时,PM 能做什么?
我现在认为,PM 对内部风险的管理重点不是“预测某个人会不会离开”,而是降低任何单点人员变化对项目造成的破坏。
课程项目中,即使没有真正遇到离职,也会遇到类似问题:某个成员临近期末突然变忙,某个模块只有一个人懂,某次联调时关键同学不在线。这些情况本质上都是“人员风险”的轻量版本。
在 HexaVigil 里,这种风险更明显。地图、战斗、单位、建筑、UI、数据、美术资源和宣传材料都分散在不同模块,如果某个模块只有一个人知道怎么改,团队就会被单点知识卡住。后来项目中大量文档其实就是在缓解这种风险:README.md 说明文档入口和 Git 协作规范,ARCHITECTURE.md 描述项目骨架和模块归属,INTERFACE.md 说明模块之间允许怎样交互,DATA_SCHEMA.md 说明数据表字段,UI_SYSTEM.md 说明 UI 分层和重构方向。
所以 PM 能做的事情包括:
- 通过文档、接口约定、代码注释和测试,减少知识只存在于某个人脑子里的情况;
- 让核心模块至少有两个人了解,避免形成单点依赖;
- 定期同步进度和困难,及早发现成员掉队,而不是等到 deadline 前爆雷;
- 对任务进行拆分和优先级排序,保证即使有人临时缺席,项目仍能保住核心功能;
- 当风险发生时,先稳定范围和节奏,再追究原因。
我现在更倾向于把 PM 看成“系统稳定器”。PM 不一定能控制每个风险发生,但可以提前设计团队结构,让风险发生时损失可控。
6. “小强地狱”中,Bug 数量阈值能平衡开发与修复吗?
这个问题在测试实践后变得更清楚了。单纯用 Bug 数量做阈值是不够的,因为 Bug 的严重程度差异太大。一个核心逻辑 Bug 可能比几十个 UI 小问题更值得立即处理。
在花见小路项目中,我们最重视的不是 Bug 数量,而是它是否破坏核心规则。例如 T2 中 history 解析错误会导致整局状态复原错误,这类 Bug 必须优先修;而某些边界输入的报错信息不够优雅,虽然也需要处理,但优先级显然较低。
因此,我现在认为更合理的方式是“严重程度 + 阻塞程度 + 数量”一起判断:
- P0:导致程序崩溃、核心结果错误、无法提交或无法运行,立即修复;
- P1:影响主要流程或测试连续性,应优先进入当前迭代;
- P2:体验问题、低频边界问题,可以排期;
- P3:优化建议或代码清理,不应打断当前开发节奏。
“小强地狱”的价值不是惩罚开发者,而是提醒团队技术债已经影响交付。如果机制让大家开始隐藏 Bug、拆小 Bug、或者抢着交半成品,那就是指标设计出了问题。
7. 软件的“防呆设计”和“功能强大”如何平衡?
我现在认为,这个问题要回到用户场景,而不是抽象地比较“简单”和“强大”。
防呆设计适合高频、低容错、面向普通用户的操作,例如删除数据、支付确认、权限授权。功能强大适合专业用户、高价值任务和可学习的深度工作流,例如图像编辑、代码开发、数据分析。
二者并不是非此即彼。很多产品可以通过分层设计同时满足不同用户:
- 默认路径保持简单,让新用户不容易犯错;
- 高级功能折叠在二级入口或设置中,不干扰主流程;
- 危险操作提供确认、撤销、预览或版本恢复;
- 对专业用户提供快捷键、批量操作和可配置能力。
在作业二对网易云音乐的分析中,我也意识到:一个产品不一定要把所有能力都堆到首页。对于音乐软件来说,核心听歌路径应该尽量防呆和轻量;而播客筛选、云盘映射、推荐偏好调整等复杂功能,可以通过更专业的入口提供给需要的人。
8. 创新在软件工程课程作业中是必须的吗?
我现在的答案是:创新不是必须“看起来新”,但必须“对问题有价值”。
课程项目时间有限,团队规模也有限。如果为了创新而创新,很容易做出炫技但不可用的功能,最后核心需求反而没做好。真正有价值的创新应该建立在可靠交付之上。
在结对项目中,我们并没有追求特别复杂的 AI 策略,比如直接上 MCTS 或 CFR,而是先实现可运行、可解释、不会超时的启发式策略。这看起来不够“炫”,但符合课程项目的资源边界。对我来说,这也是一种工程上的成熟:先交付稳定基线,再在边界内优化。
HexaVigil 也让我重新理解了“创新”的边界。项目本身的想法并不小:把明日方舟式塔防、探索迷雾、资源经营、随机事件、肉鸽遗物和九天三幕结构结合在一起,还要做地图生成、夜晚词缀、Boss 双形态和可视化路线预览。这样的项目如果继续无限加机制,很容易失控。真正值得坚持的创新,不是堆更多设定,而是让核心循环成立:白天的探索和基建选择会影响夜晚防守,夜晚战斗结果又影响后续遗物和资源策略。只有这条链路跑通,创新才不是装饰。
所以在高校软件工程课程中,PM 应该把创新放在“锦上添花但不牺牲主线”的位置。核心功能、可运行性、测试和协作流程是地基;创新应该围绕真实痛点做小而准的改进,而不是把项目拖向无法完成的宏大叙事。
二、仍然不明白的问题
课程结束后,原来的问题大多有了实践层面的回答,但仍有一些地方没有完全想清楚。
1. 工程取舍是否存在可量化的标准?
比如“什么时候应该重构”“什么时候应该结对”“什么时候应该打断 Sprint”,我现在能给出一些经验判断,但这些判断仍然依赖团队经验。是否存在更系统的量化方法,例如结合缺陷率、变更频率、模块复杂度、沟通成本等指标,帮助团队更客观地做取舍?这一点我还没有完全掌握。
2. 用户真实需求到底能验证到什么程度?
通过调研、访谈和原型测试,我们可以减少偏见,但似乎永远无法完全消除偏见。很多需求只有产品上线后,在真实使用场景中才会暴露。如何在课程项目这种时间短、用户少的环境中尽量提高需求判断质量,仍然是我觉得困难的问题。
3. 团队管理中的“人”的问题仍然最难
技术问题往往可以通过查资料、写测试、重构解决,但团队成员动力不足、沟通不顺、责任边界模糊这类问题更复杂。PM 应该介入到什么程度,如何既推动进度又不造成压迫感,我还需要更多实践才能理解。
三、新产生的问题
学习完这门课后,我也产生了一些新的问题:
- 当团队使用 AI 辅助开发时,如何界定“个人能力”“团队产出”和“工具生成”的边界?代码可以由 AI 帮助生成,但需求理解、测试设计和责任归属仍然需要人承担,这会不会改变软件工程课程的评价方式?
- 在课程项目中,如何平衡“工程规范”和“快速完成”?如果严格执行代码审查、测试覆盖、文档维护,时间成本很高;但如果完全追求速度,后期又容易失控。
- 对于小团队项目,怎样的文档粒度最合适?文档太少会导致交接困难,文档太多又可能变成维护负担。
- 如何评估一个团队项目真正“成功”?是功能完成度、用户满意度、代码质量、展示效果,还是团队成员的成长?
四、六个阶段中学到的知识点
软件工程强调“做中学”。这门课给我最大的改变,是让我意识到需求、设计、实现、测试、发布、维护不是六个孤立步骤,而是互相影响的一条链。
1. 需求阶段:需求不是功能列表,而是问题定义
知识点:需求分析要区分“用户提出的解决方案”和“用户真正遇到的问题”。
在作业二分析网易云音乐时,我发现“推荐更准确”只是表层表达。背后的真实问题可能是用户不想被偶发行为污染推荐,也可能是用户想减少找歌成本,还可能是用户希望在某个场景下保持沉浸。需求阶段如果只记录“加一个推荐调节按钮”,就会过早进入方案;更好的做法是先明确用户痛点,再比较不同方案。
团队项目 HexaVigil 中,我对需求的理解又进了一步。我们不是在做一个“功能越多越好”的游戏,而是在做一个有稳定核心循环的策略游戏。最开始大家很容易提出很多酷功能:更多干员、更多 Boss、更复杂事件、更炫的 UI、更多地图机制。但真正进入需求分析时,必须先问:这些功能是否服务于“白天探索和建设、夜晚防守、战后肉鸽成长”这个闭环?比如封堵出怪口、随机事件、遗物、夜晚词缀都不是孤立功能,它们都在影响玩家每天的风险判断。需求阶段最大的收获是:项目愿景必须被拆成可验证的核心循环,否则团队会被功能清单淹没。
2. 设计阶段:高内聚、低耦合不是口号,而是降低变化成本
知识点:把容易变化的部分和稳定的部分隔离。
在结对项目中,我们把角色分值、胜负判定、历史记录解析、策略选择尽量拆开。这样 T1 的判定逻辑可以服务 T2/T3,而不是每一章都重写一遍。设计阶段不一定要设计得很复杂,但要想清楚哪些概念应该独立存在。
HexaVigil 的设计阶段让我真正体会到“架构文档”的意义。项目里 GameController 管阶段流转,RunState 管运行时公共状态,DataRepo 管配置读取,地图、建筑、单位、敌人、波次和 UI 各有独立模块。跨模块通信主要通过直接调用、EventBus 信号和 Godot Group 三种方式完成,并明确要求 UI 只显示和发请求,不保存业务真相数据。这个边界非常重要:如果 UI 能直接改地图、单位或资源,短期写起来快,长期联调一定会乱。设计阶段我学到的知识点是:架构不是为了显得专业,而是为了让多人并行开发时不互相踩到对方的状态。
3. 实现阶段:可读性和可调试性也是功能的一部分
知识点:代码不仅要能运行,还要能被队友理解和修改。
个人写代码时,我常常更关注“能不能 AC”;但在结对和团队项目中,代码要被别人阅读、复用、测试。比如表驱动、辅助函数、清晰命名、防御性返回,这些看似不直接增加功能,却能降低后续联调成本。实现阶段最重要的不是炫技,而是把复杂逻辑写得稳定、清楚。
在 HexaVigil 的实现中,数据驱动给我留下了很深印象。干员、敌人、建筑、遗物、事件、波次和 UI 图标都尽量放在 data/ 下的 JSON 配置里,代码通过 DataRepo 读取。这样实现新内容时,很多时候不是去改核心脚本,而是补数据、补资源、补字段解释。比如单位的生命、攻击、防御、阻挡、攻速、范围、SP、技能参数等都在配置表中描述;建筑也通过 building_type、sort_order、资源消耗、图标路径等字段驱动 UI 和建造逻辑。这让我意识到,实现阶段的“写代码”不只是写脚本,也包括建立稳定的数据表达方式。
4. 测试阶段:测试是对需求理解的再确认
知识点:测试用例应该覆盖规则、边界和异常,而不是只验证“正常能跑”。
在花见小路项目中,我们为 11 分胜利、4 枚胜利、第三轮同分、输入异常等情况设计测试。写测试时经常会反过来发现自己对题意理解不完整。测试不是开发结束后的附属工作,而是帮助我们澄清需求和设计的工具。
团队项目的测试更接近“系统验证”。HexaVigil 这种 Godot 游戏项目,很多问题不是一个函数单测能发现的,而是要看完整链路是否能跑通:地图生成后是否保证出怪口到核心可达,迷雾探索是否正确揭示 3×3 区域,白天建造是否正确扣除行动力和材料,夜晚波次是否按预览出怪,封堵出怪口是否只影响当晚,战斗结束后是否正确进入遗物选择。项目还配置了 GitHub Actions 做 Godot CI,合入前需要通过构建检查。这让我意识到,团队项目里的测试不仅是“测结果”,也是保护主干可运行状态。
5. 发布阶段:发布不是“代码写完”,而是把产品交到使用环境中
知识点:发布需要考虑构建、运行环境、说明文档、演示路径和风险预案。
课程作业中,即使只是提交代码和博客,也会遇到环境配置、依赖安装、运行命令、仓库链接、截图材料等问题。一个项目如果只能在开发者自己的电脑上运行,就还没有真正完成发布。发布阶段让我意识到,可复现性和说明文档同样是工程质量的一部分。
HexaVigil 的发布阶段还包含了更完整的产品化工作:Godot 导出预设、Windows/Web 打包 CI、宣传片计划、Demo 稳定性、主分支和开发分支管理等。README.md 中明确了 dev 和 main 的区别:dev 保持日常开发可编译,main 只用于稳定版本、Demo、Alpha 或发售版本。所有改动通过 PR 合入,PR 关联 Issue,合并前等待 CI 和 Code Review。这个流程让我意识到,发布不是最后一刻打包,而是整个开发过程中持续维护“随时能交付”的状态。
6. 维护阶段:维护不是修补过去,而是管理变化
知识点:维护阶段的核心是控制技术债和持续演进。
在迭代作业中,前一阶段写死的逻辑会在后一阶段变成负担;前一阶段留下的测试会在后一阶段成为保护网。维护不是等项目坏了再修,而是在实现时就为未来变化留下余地。真正好的代码不是永远不改,而是需要改的时候知道从哪里改、怎么验证改对了。
HexaVigil 的维护压力主要来自内容量和模块耦合。一个改动可能同时碰到数据表、UI、地图、战斗和资源文件。为了解决这个问题,项目文档中明确了数据归属:每类运行时数据只允许一个拥有者;模块协作方式也被限制在直接调用、EventBus 和 Group 三类。UI 系统还专门有 UI_SYSTEM.md 描述分层规范和后续重构清单。维护阶段我学到的是:项目越大,越不能依赖“大家心里都知道”,必须把约定写进文档、接口和流程里。
五、结合个人项目、结对编程和团队项目的心得
1. 个人项目:从“完成任务”到“管理自己”
个人项目给我的最大训练是 PSP 意识。以前我写程序基本靠感觉,觉得一个任务“应该很快”,结果经常在调试、环境配置和边界情况上花掉远超预期的时间。记录预估耗时和实际耗时后,我发现自己最容易低估的是测试和报告整理,而不是编码本身。
这让我意识到,个人开发能力不只是写代码能力,还包括估时、拆分任务、记录问题、复盘改进的能力。软件工程首先是一种自我管理方式。
2. 结对编程:两个人不是分摊工作量,而是提高反馈质量
结对编程让我真正理解了“共同代码所有权”。在花见小路项目中,一个人写代码,另一个人对照规则、设计测试、检查边界,这种反馈比事后 review 更及时。
我印象最深的是 T2 的 history 解析。一个人很容易在自己的假设里写出“自洽”的解析逻辑,但搭档拿题面例子一读,就能发现某个分支隐含了错误前提。结对的价值不一定体现在速度上,而体现在减少返工、暴露盲区、共享理解上。
当然,结对也需要成本。讨论不能无限发散,争论最后必须落到代码、测试或文档里。否则看起来很热闹,实际上没有产出。
3. 团队项目:软件工程最终是协作工程
团队项目 HexaVigil 让我更深地意识到,项目失败往往不是因为某个人不会写代码,而是因为需求没对齐、接口没约定、进度不同步、风险没人管。
HexaVigil 是一个 Godot 肉鸽塔防项目。它的核心循环是九天三幕:白天玩家用行动力探索迷雾、采集资源、建造基建、触发随机事件、招募和部署干员;夜晚根据当天激活的出怪口和夜晚词缀进入塔防战斗;战斗结束后进行遗物三选一,并推进到下一天。这个项目的复杂度远高于个人项目和结对项目,因为它不是单个算法或单个页面,而是一组互相咬合的系统。
在这个项目里,我第一次很直观地感受到“模块边界”的价值。地图模块负责 30×30 地图生成、地形、资源点、迷雾和刷怪口;建筑模块负责建造、损毁和修复;单位与商店模块负责干员实例、部署、撤退、再部署和商店刷新;敌人与波次模块负责出怪、寻路、Boss 和夜晚词缀;UI 模块负责 HUD、建筑面板、事件面板和遗物界面。每个模块都能讲出自己的职责,团队协作才有基础。
我印象最深的是项目里对“接口”的重视。INTERFACE.md 不是装饰文档,它规定了公开方法、请求类方法返回值、EventBus 信号命名和模块监听关系。比如 UI 发出 request_explore、request_buy_shop_slot、request_refresh_shop 这样的请求信号,但真正修改资源、地图和单位状态的是对应 Manager。这个规则解决了一个很实际的问题:多人开发 UI 和逻辑时,如果谁都能直接改状态,Bug 会很难追踪;如果所有状态修改都有明确入口,出问题时就能沿着接口查。
数据驱动也是团队项目里非常关键的一课。DATA_SCHEMA.md 对 units.json、enemies.json、buildings.json、buffs.json、events.json、wave_templates.json 等表做了字段说明。这样美术、数值、程序之间不必每次都靠口头解释:新增一个建筑,需要知道它属于采集类、增益类还是阻挡类;新增一个敌人,需要知道它的行为类型、移动类型、伤害、核心扣血和表现资源;新增随机事件,需要知道根事件和分支结果如何进入事件池。配置表就是团队之间的一种契约。
团队流程方面,HexaVigil 使用了比较完整的 Git 协作规范:dev 是日常开发主干,main 只用于稳定版本;功能从 feature/* 分支开发,通过 Pull Request 合入;任务和 Bug 通过 GitHub Issues 管理,并设置 Milestone 和估点标签;合入前需要 CI 和 Code Review。以前我会觉得这些流程有点重,但真正做团队项目后才明白,流程不是为了增加仪式感,而是为了保护项目不会被一次随手提交搞崩。
这个项目也让我重新理解了“文档”的价值。玩法循环与模块分工 让新人能快速理解游戏到底怎么玩;ARCHITECTURE.md 说明运行结构和模块划分;DATA_SCHEMA.md 说明数据表;UI_SYSTEM.md 说明 UI 分层;素材生成提示词文档则保证美术资产风格尽量统一。这些文档不只是期末报告材料,而是在开发中降低沟通成本、减少重复解释、减少误解的工具。
当然,团队项目也暴露了很多问题。游戏项目的内容量很容易膨胀,地图、单位、敌人、建筑、事件、遗物、UI、美术、音效都想做得更完整,但课程时间有限。我们必须不断取舍:有些数值可以先占位,有些 UI 可以先保证可用,有些机制可以先做最小闭环,有些美术可以后续替换。团队项目让我明白,工程不是把所有想法都实现,而是在有限时间里让最重要的系统可靠地连起来。
我也意识到 PM 的工作并不是“催大家干活”这么简单。PM 需要不断在范围、时间、质量和成员状态之间做取舍。一个好的团队不是没有变化和冲突,而是有机制把变化和冲突消化掉。HexaVigil 给我的最大收获是:软件工程最终不是某个人写出一段漂亮代码,而是一群人围绕同一个目标,把需求、架构、数据、代码、资源、测试、发布和文档组织成一个还能继续演进的整体。
六、总体收获
这门课让我对软件工程的理解,从“写代码的方法”变成了“组织复杂工作的方式”。
课程开始时,我更关心怎么写出一个正确程序;课程结束时,我开始关心为什么要写这个程序、需求是否真实、设计是否能承受变化、测试是否覆盖风险、队友是否理解我的代码、发布后是否还能维护。
如果用一句话总结,我觉得软件工程教会我的不是某个单独知识点,而是一种持续追问的习惯:
这是不是用户真正需要的?
这个设计以后改得动吗?
这个实现别人看得懂吗?
这个功能坏了能被测试发现吗?
这个项目交出去后还能继续活下去吗?
这些问题没有让我写代码变得更轻松,但让我写代码变得更踏实。以前我更像是在完成一次次作业,现在我开始能把一个软件当成会被别人使用、被团队协作、被时间检验的工程成果来看待。这大概就是这门课对我最大的帮助。

浙公网安备 33010602011771号