《技术领导力》笔记(3)—— 开发过程管理
产品开发过程管理
无论什么公司,都需要遵从一套成熟的产品研发过程体系,才能做出质量较好的产品。
项目启动会
目标
项目启动会的目标是明确该产品开发项目的目标,目标指导计划。目标不清晰或是过高,都会影响项目的实际结果。
准备工作
在项目启动会之前,与用户沟通并明确需求。项目启动会需要说明项目目标、阶段划分、组织结构、管理流程等关键事项,这些事项必须达成一致意见。对于关键角色任命,事前也需要听取相关领导和项目主要干系人的意见。
过程及议题
- 介绍议程和来宾
- 介绍项目目标、阶段计划、管理方法
- 发布项目的组织结构图
- 确认关键角色及其职责,并作出承诺
- 参会人员针对介绍内容进行提问交流
- 高层领导做项目动员发言,激励和鼓舞士气
- 各个相关部门领导表态支持项目工作
会议内容整理为《项目启动会议纪要》,作为项目组的第一份正式公告发布,同时宣布项目正式启动。
经验和教训
项目启动会非常重要,其意义不仅在于宣布项目启动,而且是确认人员到位的关键时间节点。会议邀请涉及部门的高层领导出席和表态,可以让项目后续的推进获得广泛支持。项目启动会一旦顺利通过,需要立即着手进行产品需求讨论、编写。
用户需求
用户需求由用户提出,对技术一般不描述,只描述产品目标。产品需求是根据用户需求转化而来的技术实现需求,需要针对用户提出的产品目标进行细分,总结出具体的功能点,再针对每一个功能点细分为各种不同的操作流程,对每一个操作流程进行技术化定义。
用户需求关注的是系统如何支撑业务流程,背后的需求是“实现业务目标”。技术人员关注的是合理的技术方案,背后的需求是“工作量”、“实现难度”和“系统性能”。
需求理解不一致
产品经理和技术人员往往不在一个频道上,召开产品或者技术方案会议的时候,最容易犯的错误就是,自己先绘制了原型图,甚至产品架构图,直接来讲解自己的方案。这是一个错误的会议方式,浪费了所有人的时间,二流产品就这么诞生了。
需求讨论会可以这么做:
- 开任何会议,不要一上来就讲解方案,应该先讲业务场景。每个场景先讨论背后的需求并定义清楚。
- 大家一起讨论,研究这个场景背后的需求是不是最佳场景,能不能删除这个场景,或者是否有其他场景可以代替这个场景,同时还能满足背后的需求。
- 如果是需求的最佳场景,再开始讨论这个场景下的产品解决方案。
- 打开事先设计好的产品原型图、流程图、状态图、用例图,你会发现有很多需要修改的地方,修改之后才是大家达成一致的方案。
产品需求
产品需求是从业务需求推导出来的,必须为业务需求服务。
产品需求编写
产品需求包括产品需求规格说明书和产品需求矩阵。
产品需求规格说明书一般包括:
- 简介:产品功能和定位简介、常用产品和技术术语、参考文献
- 产品描述:产品介绍、产品范围、产品遵循的标准
- 技术约束和局限:实现过程中需要满足的条件、受技术方面的限制,说明原因
- 需求详细描述:按功能划分,列举每一个功能的需求描述、优先级、参与者、前置条件、结果、功能执行中的正常过程、可选过程、异常过程、特殊需求、附加说明等
- 接口需求:用户接口、硬件接口、软件接口、通信接口
- 质量需求:包括性能需求、可靠性需求、可用性需求、可维护性需求、安全性需求、可移植性需求、可测试性需求
- 用户文档需求:用户指南、联机帮助手册、安装指南、配置文件
产品需求矩阵按照子系统、功能集、执行单元的结构列出所有的功能需求,每列则对应每项功能的工作步骤和工作量。
需求评审
在需求评审阶段,邀请产品、开发、测试相关人员进行需求评审。针对以下几个方面进行:
- 为什么做这个需求
- 需求的价值是什么
- 需求的上线时间
- 需求是否完整?正常场景、异常场景是什么?是否考虑周全?技术上如何应对
需求评审之后,开发人员编写技术方案,测试人员编写测试用例。接下来进行技术方案评审,技术方案必须有业务流程图和时序图。这个过程需要反复讨论,达到解决问题的目的。
总体设计
良好的系统架构设计可以帮助技术人员梳理业务逻辑并抓住核心需求,评估开发周期和成本,能有效规避风险。
总体设计是整个系统的框架设计,意义重大,不能省略。所有开发项目都要首先进行总体设计,不能本末倒置,绝不允许先编码后设计。
总体设计分三个阶段:
- 初始设计。在给定的数据流图进行复审和精化基础上,将其转化为初始的模块结构图。
- 精化设计。依据“高内聚低耦合”原则,精化初始的模块结构图,设计全局数据结构和模块接口。
- 设计复审。对前两个阶段得到的高层软件结构进行复审。
作者的这个设计思路是传统软件设计思路。微服务架构下,领域驱动设计很火爆。
概要设计和详细设计
概要设计包括组成模块,模块的层次结构,模块的调用关系,模块功能。
详细设计为每个模块完成的功能进行具体描述,设计每个模块内部的算法、流程,把功能转变为结构化的过程描述。如果需要结构调整,必须返回到概要设计阶段,更新概要设计文档。一个模块对应一个详细设计文档。
编写代码
- 优先考虑核心模块的压力测试。提前明确业务压力在哪儿。
- 写注释。下次来修改的时候,看注释就明白当时是怎么想的。
- 用人人都看得懂的逻辑。逻辑太复杂将难以维护。
- 不沉迷框架。越高端的框架,结构越复杂,难以掌控。
- 使用熟悉的技术。使用新技术的时候,要想一想能不能用到它的新特性,用不上就没必要用。
- 优化细节再谈架构。单服务器都还没用到极致,就不要谈分布式。
- 多打日志。上线初期,日志越详细,越能尽快定位问题。
代码审查
代码审查(code review)可以提升代码质量、分享项目知识。代码审查非常重要,每周都要做一次。代码审查有利于跟进项目进展,真实地看到成员的工作进度,及早发现是否误入歧途。
代码审查重点关注设计是否良好、可读性和可维护性是否具备、功能是否正确(正向和异常处理)、性能和安全是否考虑。
单元测试&集成测试&用户测试&压力测试
上线之前,必须充分测试和优化。暴雪的游戏经常跳票,甚至推迟几年才发布,但玩家们都愿意等,因为“暴雪出品必属精品”。
复盘
复盘的目的在于总结问题、分析原因,避免以后犯同样的错误,而不是追究谁的责任。会议要对项目的每一个环节进行回溯,复盘参与人员不用很多,主要是总结经验,不断优化开发过程。
产品开发过程杂谈
理解业务
所有脱离了业务场景的架构设计都是耍流氓。业务根本用不到的技术特性,如果设计出来,除了能在PPT上吹牛逼之外,实际上毫无意义,还把架构弄复杂了,不好维护。
如何理解业务?不需要你去实际做业务,只需要在需求分析阶段把业务场景弄清楚,把业务术语、涉及到的岗位、异常处理、控制规则这些都搞清楚就差不多了。
应对需求变更
我们不能抵制变更,但是要用切实有效的办法控制变更。控制变更的目的不是阻止变更的发生,而是对变更进行管理,确保变更有序进行。业务人员或者领导今天提要求,明天就上线,这是绝不允许的。
需求发生变更后,一定要同步修订相关文档,比如需求规格说明书、需求分析文档、需求跟踪矩阵等,并通过书面方式通知团队其他人员。变更管理流程必须严格执行,防止需求蔓延导致项目失控。
开发进度管理
《人月神话》有言:“向进度落后的项目中增加人手,只会使进度更加落后”。你能get到它的点吗?
人数和时间是两个独立要素,不能互相替代,你不能把“2个人花2个月”变成“4个人花1个月”。人数和时间可以互换仅仅适用于如下情况:如果某个任务可以分解给参与人员,并且他们之间不需要相互交流——在软件项目中这几乎不可能。人越多,花在沟通上的时间就越长。找人来接手别人的代码,不熟悉两三个月也上不了手。
评审的重要性
评审对于项目成功而言是绝对必要的。需求、设计、代码、测试用例都需要评审,评审是为了尽早发现问题,把缺陷在下一阶段开展之前解决,避免后期付出更大代价。
版本管理
版本管理工具很多,需要考虑怎么去使用。有的公司拉很多分支出来并行开发,最后合并的时候问题多多,互相覆盖。实力不够的公司,就用一个主线,清晰明了。
优先级安排
安排工作的顺序:重要并且紧急>重要但不紧急>紧急但不重要>不重要也不紧急。不能因为事项提出者的职务级别高,就把它的优先级排前面。
产品质量的重要性
提到质量,不得不提到暴雪。为了发布bug少,可玩性高的游戏,它宁愿延迟几年发布,但玩家们依然期待,不会因为延迟发布而转向别的游戏。
质量低下的产品,是把客户拱手送给竞争对手。做出这样的产品,一定是跟老板有仇,希望公司早点关门。
绝大多数的时间都花在处理bug造成的错误数据上了,哪儿还有时间开发新功能呢?
测试过程
一旦进度紧张,往往会选择把测试时间压缩,甚至不测试直接上线。测试是保障交付质量最有效的手段,如果放行,问题会在上线后集中爆发。
- 测试计划:确定测试目标和策略,估算工作量,确定人力资源和测试环境资源。
- 测试设计:确定测试需求,设计测试用例并评审。
- 测试实现:搭建测试环境、编写测试脚本、准备测试数据、编写测试驱动程序。
- 测试执行:测试人员根据测试用例输入测试数据、记录测试结果。跟踪问题和缺陷,修复后再验证。
- 测试完成:对测试情况分析总结,出具测试结论和建议。
编写高质量代码的难度
任何程序员都能写出机器可以阅读的代码,只有优秀的程序员才能写出人可以阅读的代码。
我们去读别人的代码的时候,我们希望这个代码写得比较简单,函数很短,命名能够让人望文生义,读起来就像读小说一样。这也是我们自己编码的时候应该要做到的目标。
迭代的意义
软件无法一次性把所有业务都模拟出来,要分步骤一点一点完成,这就是所谓的迭代。迭代的前提是确定优先级,优先实现业务的核心功能。