1. 需求

  1. 谁的需求?
  2. 解决什么问题?
  3. 实现哪些价值?
    • 明确合同价值。
    • 开发活动时间持久、干系人众多,通过价值明确出发的目标,提高干系人的产品和工程要求。
  4. 有哪些前置条件?关联需求?
  5. 验收标准?做到什么程度。
  6. 什么时候上线?

1.1. 需求不明、没有“验收标准”的困境

  1. 设计、开发人员目标模糊,工期压力下往往以自己的理解去实现,并和项目经理一起开心地完成工作。上线后用户提出修改意见,由于设计时乐观认为目标明确,故难以扩展,导致推翻原版,耽误工期。严重时尚需一个完整开发周期才能二次上线,此时假如仍没有就验收标准和用户达成一致,则陷入递归。
  2. 如1,人、项目、组织集体失控,无法有条理地开展后续工作。
  3. 过程混乱降低团队平均水位,导致干系人降低对己要求、并提高对他人要求,相互抱怨、推诿,团队协作力断崖下跌。
  4. 干系人对工作缺乏幸福感,对组织失望,离职或提出更高待遇要求才能填补内存空缺,因为他们集体认为这是组织的流程故障。

上述后3条困境对于流程不足的团队,始终存在。工作方式和流程看上仅针对某些具体行为,实质上最后直指人心,上述后2条的影响更深远。

2. 版本管理

  1. 代码仓库推荐git和gitlab,还可放入github的私人仓库。
  2. 凡是和项目/产品有关的东西均要放入代码仓库,除该代码编译后的二进制文件(如库和可执行程序)和构建过程中临时文件,比如:
    • 文档
    • 代码
    • 重要邮件记录
    • 图片
    • 依赖资源(ffmpeg库、opencv库)
    • 测试脚本
    • 构建工具脚本
  3. 版本管理的目标是一位新成员加入后,通过下载仓库内容后一键构建,而无需其他手工操作。
  4. 每日提交,确保每次提交版本均可编译通过,包括debug/release以及x86/x64。不用担心一项功能还没开发完成而等待1周或更长时间才去提交,假设果真如此,你需要创建独立分支。
  5. 当一项功能会被不同仓库使用时,建议把她独立成子仓库。
  6. 每个项目如github上开源项目一样,提供符合Markdown语法的README.md和Changelog.md,随同安装包一起发布,如下示例。
    • README.md文件:
       ## 背景
       ## 依赖
       ## 构建
       ## 测试
       ## 示例
      
    • Changelog.md文件,随同安装包一起发布,如下示例: ```c version:2.1.6.0
    • 2018-10-08
    • refs #1923:修复从任务计划中启动时保存新配置settings.jsonC://windows/system32目录,而不是安装目录下。 ```
  7. 每个软件必须自带版本号:一种产生软件版本号的方法
    • 该方法中采用git命令来获取git提交号,根据该提交号唯一定位到源码,极力避免发布产生dirty字样的版本。
    • 每个软件都可通过命令行敲入-v参数,然后输出版本号到标准输出。如果是独立库,则提供const char *foolib_get_version()类似API,返回一个字符串常量。

2.2. 代码分支

  1. master分支作为稳定分支,通常基于某个打过标签的稳定分支,也许存在一些无关紧要的修改。
  2. develop分支是开发主分支,日常工作都基于她。
  3. 遇到重要功能、大功能、重要算法实现、性能改善或是修复较大、较重要的bug时,可独立出1个新分支,该分支命名规则是:branch_refs_{id}_{description}
    • refs来自redmine习惯,代表references
    • {id}表示对应redmine任务号。
    • {description}可简短描述分支目标。
  4. 离开公司内网环境后继续开发,可寻找某个公网上git服务(如bitbucket)作为远程仓库、并提交过去,使得可继续与公司内同事共享你的成果,回到公司后及时推送到内网gitlab。

3. 项目管理

3.1. 工具

  1. Redmine使用笔记
  2. 禅道:敏捷开发

3.2. 实践

  1. 每项任务的进度安排获得研发人员的首肯,如果没有按时完成,需总结原因、并相应加班,特殊情况除外。
  2. 每周一上午周会。
  3. 每日项目管理软件上的任务进度报告。
  4. 每周四下午:14:00,各个研发人员演示产品。需要时测试人员参与。

4. 设计

  • 未完待续

5. 评审

5.1. 设计评审

  • 选择重要、困难、涉及多人配合的接口部分等功能,做出相应的设计资料,举行评审。
  • 先完成基本设计(架构图、模块图、重要时序图,PPT/Redmine上Wiki/README.md形式),经过自我反复评审、相关人评审后再coding。
  • 把想做的写出来、讲出来,对目标和内部的拆解,自然而然地变得清晰。
  • 设计尽量一次性作对,但不能绝对,许多不熟悉、有挑战的工作,在开头阶段由于信息不对称难以窥其全貌、做出完善的设计,此时可以先有几处的设计,然后开展工作,过程中不断完善。
  • 先做对、再做好,快速迭代。

5.2. 代码Review评审

6. 软件发布

  1. 发布必须有脚本或类似构建工作,而不是人工Copy。
  2. C/C++/Python的编译工作也放入某种脚本如Windows上批处理或Python脚本。
  3. 发布软件压缩包名称中带有:软件名+大版本+git提交号+作者+分支名+构建时间,比如Foo_V2.1.0_git_20a688e(git_{author}_{branch}_20181024001024).zip
  4. 开发人员根据新版本软件的目标,比如修复bug或加入新功能等,完善测试用例文档,看上去类似TDD测试驱动开发(Test-Driven Development)。
  5. 开发人员开发完成后,递增软件版本号、发布新版到自己(不是测试团队)的测试环境,根据测试用例自行测试,此时也可能会再次更新测试用例。
  6. 频繁发布到公司内测试环境:前提是以较大周期发布时没有有效地测试手段,而使得发生错误的可能性更大。
  7. 凡是发布到生产环境的,必须同步发布到公司内环境。
  8. 发布时仓库中编写好Changelog.md文件中的说明,通过邮件发布给测试组申请测试,并抄送给相关人员。

7. 邮件

  1. 发布新版本时构建好软件包后,作为邮件附件或某个FTP地址,通过邮件群发通知关联人员,比如测试组、上下游使用方。
  2. 邮件正文应说明软件变更内容
    • 什么软件
    • 什么版本,包括大版本和小版本(git或svn commit)
    • 和上一个版本的变化,包含源码仓库中Changelog.md文件的最后一次变更内容,以及下载地址,如:
    1. 升级说明
      • version:2.1.6.0
      • 2018-10-08
      • refs #1923:修复从任务计划中启动时保存新配置settings.jsonC://windows/system32目录,而不是安装目录下。
      • 下载地址: ftp://x.x.x.x/Products/Foo_V2.1.0git_20a688e(git{author}_{branch}_20180902).zip

8. 持续交付与Jenkins实践

9. 决心

  1. 管理层保持决心,拥抱变化。