构建之法阅读笔记01

一、我过去是怎么做的(以及我看到身边人是怎么做的)
在过去两年的课程设计、实训项目和个人小工具开发中,我始终沿用着一套极其粗放的开发模式,甚至可以说是 “毫无流程可言”。
拿到一个开发需求时,我从来不会做前期的规划和设计,更不会拆解功能点、预估耗时,往往是扫一眼需求文档,脑子里大概有个模糊的实现思路,就立刻打开编译器上手写代码。我总觉得 “先把架子搭起来,边写边调整才最高效”,把前期设计当成 “浪费时间的纸上谈兵”。比如做课程设计的学生管理系统时,我连数据库表结构都没画完整,就先写了前端页面和登录接口,写到后面才发现表结构的外键关联有问题,不得不回头推翻重写,前后改了三四版才勉强跑通。
而对于单元测试,我更是完全持轻视甚至排斥的态度。我一直觉得,单元测试是额外的工作量,是 “为了应付规范而做的表面功夫”,只有等整个功能模块全部写完,我才会跑一遍主流程,看看能不能正常运行。只要核心功能不报错,边缘情况、异常输入、边界值我基本都不会测试,更别说为每个函数、每个分支写专门的测试用例了。遇到 bug 就靠断点调试逐行排查,东改西补,常常是改了一个 bug,又不小心破坏了原有逻辑,引出新的 bug,陷入 “改 bug - 出新 bug - 再改” 的恶性循环。印象最深的是一次实训项目,我写的金额计算函数,只测了正常的整数输入,没考虑小数精度和负数输入的情况,直到项目验收时才被老师发现,当场出现了计算错误,场面十分尴尬。
我身边的同学大多也是如此,甚至有更极端的情况:有的同学代码写完了,连编译都没通过就直接提交到仓库,觉得 “写代码是我的事,测试是后面的事”;有的同学为了赶截止日期,只要主流程能跑通,哪怕代码里有警告、有未处理的异常,也直接交付,完全不考虑后续的维护成本。我们都陷入了一个误区:把 “写完代码” 当成了开发的终点,却忽略了 “写对代码、写好代码” 才是核心。
二、结合书中所讲,说明为什么这样不好
《构建之法》中明确指出:“软件的质量,不是事后测出来的,而是从开发的第一行代码开始,一步步构建出来的。” 对照书中的理论,我过去的开发模式,从根源上就埋下了无数隐患,看似 “高效”,实则是用前期的偷懒,换来了后期成倍的时间成本和质量风险,具体问题集中在以下三点。
第一,跳过前期设计、边写边改的开发模式,完全违背了 PSP 个人软件开发流程的核心逻辑,最终只会导致开发效率低下、代码质量失控。书中详细讲解了 PSP 的核心价值:它把个人开发拆解为计划、需求分析、设计、编码、测试、复盘六个明确阶段,让开发者对整个开发过程有完全的把控,而不是凭感觉做事。我过去的做法,直接跳过了计划和设计阶段,相当于 “闭着眼睛开车”,写代码的过程中不断推翻之前的逻辑,频繁重构代码结构,不仅导致开发时间远超预期,还会让代码的耦合度越来越高,逻辑越来越混乱,最终变成连自己都看不懂的 “屎山代码”。书中特别强调,“工程师的时间,大部分不是花在写新代码上,而是花在调试和修改旧代码上”,而我边写边改的模式,本质上就是在不断给自己制造调试和修改的麻烦,完全是本末倒置。
第二,轻视单元测试、只做主流程黑盒测试的做法,是导致 bug 频发、修复成本飙升的核心原因。《构建之法》中用整整一节的内容强调了单元测试的重要性,明确了几个核心原则:单元测试必须由代码的作者来写,因为只有作者最清楚代码的逻辑边界;单元测试要覆盖代码的所有执行路径,包括正常情况、边界值、异常输入和非法输入;单元测试要在开发的早期就完成,而不是等功能全部写完再补。我过去的做法,完全违背了这些原则:我把测试当成了开发的 “收尾工作”,而不是贯穿开发全程的核心环节,导致很多低级的逻辑错误,直到开发的最后阶段才被发现。书中给出了一个关键结论:bug 发现得越晚,修复的成本就越高。在需求阶段发现问题,修复成本是 1;到了编码阶段,成本变成 10;到了发布验收阶段,成本会飙升到 100。我过去的经历完全印证了这个结论:很多在写代码时随手就能通过单元测试规避的 bug,我到了项目验收时才发现,不仅要改代码,还要重新测试整个模块,甚至要调整关联的其他功能,花费的时间是写单元测试的十几倍。更严重的是,不做单元测试就无法做回归测试,我每次修改 bug 后,都无法验证修改是否影响了原有功能,常常是 “拆东墙补西墙”,bug 越改越多。
第三,无量化、不复盘的开发模式,让我始终无法实现个人能力的持续提升。《构建之法》中提到,PSP 的另一个核心价值,是让开发者能够量化自己的开发过程:记录自己的开发耗时、bug 率、测试覆盖率,通过复盘找到自己的短板,针对性优化。而我过去的开发,完全是 “黑盒模式”,从来不会记录自己写一个模块要花多久,调试 bug 又花了多久,也不知道自己的 bug 大多出在什么环节,只会笼统地觉得 “我这次写得慢,是因为技术不行”,却找不到具体的问题所在。这种没有量化、没有复盘的开发,哪怕做再多的项目,也只是低水平的重复,无法形成真正的能力成长,这也是我做了很多课程设计,却始终觉得自己的开发能力没有质的提升的根本原因。
三、提出一个解决办法,避免再次掉入陷阱
针对以上问题,结合《构建之法》中的理论,我制定了一套可落地、可执行的个人开发规范,彻底告别过去粗放式的开发模式,具体分为五个核心步骤,未来所有的个人开发项目都将严格执行。
第一步,项目启动前,必须完成 PSP 全流程规划与设计,绝不 “先编码后思考”。拿到需求后,我会先完成三个核心动作:一是需求拆解,把大的项目需求拆分成可落地的功能模块,再把每个模块拆分成最小的功能点,明确每个功能点的输入、输出和验收标准;二是耗时预估,为每个阶段(需求分析、设计、编码、测试、复盘)预估具体的耗时,制定详细的开发时间表,明确每个功能点的交付时间;三是设计落地,先完成数据结构设计、模块接口设计、核心逻辑流程图,输出完整的设计文档,确保所有逻辑都想清楚、画明白之后,再打开编译器写代码。为了避免自己偷懒,我会把设计文档作为开发的前置条件,设计文档没完成,绝对不写第一行代码。
第二步,全面推行 TDD 测试驱动开发模式,把单元测试贯穿编码全程,彻底扭转 “先编码后测试” 的错误习惯。《构建之法》中提到的 TDD 模式,是解决单元测试缺失问题的最优解,核心逻辑是 “先写测试用例,再写实现代码”。具体执行中,我会针对每个功能函数、每个模块,先完成四件事:一是定义清楚函数的功能、输入参数和返回值;二是编写覆盖所有场景的测试用例,包括正常输入、边界值、异常输入、非法输入四大类,比如金额计算函数,必须覆盖零值、最大值、负数、多位小数、非法字符等场景;三是运行测试用例,此时因为还没写实现代码,所有用例都会失败;四是编写实现代码,直到所有测试用例全部通过。只有当前模块的所有单元测试全部通过,才会进入下一个模块的开发,从根源上规避低级逻辑错误。同时,我会设定明确的测试覆盖率要求,每个项目的单元测试行覆盖率必须达到 80% 以上,核心功能模块必须达到 100%。
第三步,建立严格的 bug 修复与回归测试规范,杜绝 “改 bug 引新 bug” 的恶性循环。我会制定两条铁律:一是所有 bug 修复,必须先复现 bug,再补充对应的测试用例,确保这个 bug 能被测试用例精准捕获,再修改代码,直到新增的测试用例和原有所有测试用例全部通过,才算修复完成;二是任何代码修改,无论是 bug 修复还是功能优化,提交前必须全量运行所有单元测试,确保修改不会破坏原有功能的正常运行。同时,我会建立个人 bug 台账,记录每个 bug 的出现场景、原因、修复方案和复盘总结,避免重复踩同一个坑。
第四步,全程量化记录开发数据,项目结束后必须完成复盘总结。在开发的全过程中,我会用表格详细记录每个阶段的实际耗时、每个功能点的编码时长、调试 bug 的时长、测试覆盖率、bug 数量与分布,把原本模糊的开发过程,变成可量化的数据。项目完成后,我会召开个人复盘会,做三个核心对比:一是对比预估耗时和实际耗时,找到自己耗时超出预期的环节,分析原因;二是对比 bug 台账,找到自己最容易出错的逻辑场景,针对性地补充知识短板;三是总结本次开发中做得好的地方和踩过的坑,形成个人的开发经验库。通过这种 “量化 - 复盘 - 优化” 的闭环,让每一次项目开发,都能带来实实在在的能力提升。
第五步,建立个人代码提交规范,用强制约束倒逼良好习惯的养成。我会为自己的 git 仓库设置提交门禁,制定三条不可突破的规则:一是代码提交前,必须全量通过所有单元测试,测试不通过的代码,绝对不允许提交;二是每次提交的代码,必须有明确的提交信息,说明本次提交的内容,禁止 “更新代码” 这种模糊的提交信息;三是每次提交的代码量不超过 500 行,避免一次性提交大量无法 review 的代码,确保每一次提交都可追溯、可验证。
结尾总结
这一章的阅读,给我最大的启发是:专业的软件工程师,和业余的代码爱好者,最大的区别从来不是会不会写代码,而是有没有一套科学、规范、可迭代的开发流程。过去我总觉得,流程和规范是束缚创造力的枷锁,现在才明白,真正的规范,是帮我们避开陷阱、提升效率、保障质量的基石。未来我会把这套 PSP 开发流程和单元测试规范,落实到每一次代码编写中,从 “能写出代码的人”,变成 “能做好软件工程的人”

posted @ 2026-03-13 22:18  姜乐融  阅读(28)  评论(0)    收藏  举报