《构建之法》里有一个16周的软件工程课程进度设计。本文在该基本设计的基础上,围绕github.com(源码管理)、travis-ci.org(持续集成)、单元测试工具、日志工具、少数实用UML类型等工具的使用注解每个环节的实践示例,并在每个环节部分,提到课本里相关章节强调的软件工程知识点。教师可以参考设计,助教可以参考点评和评分涉及的关键点。要组队开发好的软件,需要优秀的程序员,优秀的工程素养,虽然这里提的都是程序之外的所有事情,然而真正要做出好的软件,优秀的程序是关键的基石,唯此,工程/工具才用的上力,请认清这点,否则,只会迷失在形式之下。
PS: 如果因为网络原因,可以做如下组件替换:
- github.com替换为git.oschina.net 或者coding.net,其中coding.net个人项目的issue功能不能用,gitosc的可以。
- 可免费创建5个私有仓库的google git服务,内置了构建和测试:google:source-repositories
- travis-ci.org替换为flow.ci
替换成国内组有好处也有坏处,在网络不是什么大问题的情况下,推荐使用github组合。
模块
基本上,我认为坚持从学期开始就定下:个人项目->结对项目->案例分析->团队alpha->小组互评->团队beta 这样一个路线是最佳的,这个模式足以让教师、学生、助教之间达到一个路线清晰的课程合作过程。
个人编程,写一个命令行程序
- 注册Github账号,建立项目仓库
- 添加ReadMe.md并编辑,描述项目的简要介绍、功能、用例、下载、文档等
- 建立doc目录存放文档
- 建立src目录存放源码
- 建立test目录存放测试脚本极其数据
- 建立PSP表格,预估下述几个过程的耗时估计
- 分析程序的需求,并提交文档到github
- 基本需求
- 扩展需求
- 高级需求
- 功能设计,并提交文档到github
- 使用WBS分解功能
- 确定功能优先级,选定第一个版本要解决的核心需求
- 针对选定需求设计实现方案,绘制流程图
- 在github的Issue面板上建立milestone,确定开发周期,添加所有的任务到milestone的issue列表
- 程序实现与测试
- 根据流程图分解函数、实现并完成初步逻辑、人工冒烟测试通过,提交代码到github
- 每完成一个issue,就去issue面板关闭该issue。
- 针对重要的核心函数实现单元测试、考虑所有可能的输入输出,提交单元测试代码到github
- 单元测试可以使用工具:JUnit、CUnit、NUnit等
- 能在函数的开头部分,对函数的参数添加Assert,对参数条件应该符合的假设做断言,例如指针不应该为NULL:
assert(p!=NULL);
。
- 使用一种日志系统,针对代码的关键路径,添加必要的分级别的日志
- 日志应该有基本的分级:INFO、WARN、DEBUG、TRACE、ERROR
- 可以使用著名的日志框架,例如log4cpp、log4net、log4j等,也可以是自己山赛等版本。
- 针对命令行程序、使用batch、shell脚本添加功能测试例子,提交功能测试脚本和用例到github
- 程序发布
- 通过测试的代码,通过
git tag 0.0.1
+git push origin 0.0.1
推送到github上,会在release目录下出现该tag版本的源码打包 - 编译的程序可以发布一个二进制包 xxx-debug-0.0.1.zip,并在github README的Download里加入下载链接。
- 通过测试的代码,通过
- 发布博客
- 博客排版请使用MarkDown:http://www.cnblogs.com/math/p/se-tools-001.html
- 发布一个博客,包含程序的上述所有过程描述
- 统计实际每个过程的耗时,添加到PSP表格里,并对比分析,用于下一次迭代的改进
- 阶段自我评价:http://www.cnblogs.com/xinz/p/3852177.html
结对编程,两人合作编写程序
- 两人互相认识、介绍各自的技术栈、爱好、建立伙伴关系
- 两人学习下领航员、导航员的关系、确认下彼此的角色定位
- 两人确定项目选题、源码仓库、需求分析、功能设计继承个人项目的做法继续往下走,进入磨合阶段
- 建立结对项目的任务分解和时间预估
- 两人根据项目采用的语言、学习并建立编码规范、提交到源码仓库、在提交代码前结对检查代码确认是否符合编码规范
- 两人结对实现程序的开发、单元测试、功能测试,进入协作阶段
- 结对项目开始,使用travis-ci.org对github的项目做持续集成测试
- 两人合作完成程序的发布和打包
- 两人各自写结对编程的博客报告,包含上述每个过程
- 统计每个任务的耗时,并作对比
案例分析项目
- 找案例分析项目的5-10个BUG,猜测BUG产生的原因、提供解决建议
- 分析案例分析项目的功能分解、在后面自己项目做WBS的时候请参考
- 估计项目的开发周期,学习并使用耗时估计公式
- 案例分析可以找产品所在的企业合作,并请该企业的软件工程师参与点评与反馈,参考:http://www.cnblogs.com/easteast/p/5854463.html
团队项目alpha阶段
- 组建团队,包含以下部分:
- 建立团队博客、一个团队的所有开发活动报告都在此博客上发布、如果是分别记录的、团队博客上应该有一个汇总贴
- 建立团队的Github organization, 在该组织下建立团队项目,邀请成员加入
- 参考:http://www.cnblogs.com/greyzeng/p/6044837.html
- 4人以上组队,除非特殊原因,一个团队应该至少4个人,教师可以确定种子队员、种子队员可以招募
- 学习国内外公司的Github组织和项目:
- 团队确认谁当Project Manager,大家都要学习并理解Project Manager应该具备哪些技能、有哪些职责
- 如果你是组员,你是否理解Project Manager的职责
- 如果你是组长,你是否理解Project Manager的职责
- 团队确立共同的目标,建立充分授权和信任的意识
- 如果你是组员,你理解团队的目标和个人的目标么之间的差异么,怎样取得共识?
- 如果你是组长,你理解团队的目标和每个组员的目标么,怎样最大化共识?
- 如果你是组员,你会在理解了共识的基础上和组长及其他组员充分信任么?
- 如果你是组长,你会在理解了共识的基础上和每个组员建立充分信任么?
- 如果你是组长,你理解每个人内心真正的意愿并充分授权和分解任务么?
- 学习、讨论、并建立团队的贡献分分配规则、贡献分分配应该体现成员的贡献度,教师应明确拒绝平均分规则
- 如果你是组员,你理解贡献分平均分配和非平均分配的区别么?理解绩效的目的。
- 如果你是组长,你理解贡献分平均分配和非平均分配的区别么?理解绩效的目的。
- 建立团队的编码规范,Project Manager要主动对成员提交的代码做Code Review,维持编码规范的有效性
- 为什么我们总是制定了一些美好的规则,然后束之高阁,怎样才能把美好的规则落地?
- 发布团队建立博客以及上述各部分内容、拍照一张
- 使用NABCD方法对团队项目做需求分析
- NABCD是一个形式么?
- 如果是一个形式,我为什么要用它?用它能达到效果么?怎样让形式真正发挥作用?
- 找到10个人的真实用户做项目需求分析,软件的整个开发周期中应该定期向这10个早期用户发布可用软件,寻求测试和反馈
- 需求分析部分,不能只有团队自己的“洞见”,必须要有真实用户的调研部分导致的结果,用户调研要求至少使用一个以上的用户调研方、例如 卡片、问卷、并提供真实数据。
- 针对同类产品中的3个顶级产品做竞品分析,竞争力部分要有说服力
- 学习产品发布的路径、并确定产品发布和推广的方式、产品发布的时候要确实按此路径发布或推广
- 以上提交Github的doc目录
- NABCD是一个形式么?
- 使用WBS做项目的功能分解
- 编写详细设计Specification
- 使用原型工具设计GUI的原型,并发布博客
- 合理使用UML工具建立项目的用例图、具体功能的时序图、具体算法的流程图等
- 拆解WBS的分解到Github的Issue列表,建立alpha阶段的milestone
- 使用耗时估计公式对功能开发环节做出具体的估计
- 进入敏捷冲刺开发阶段,确立10天的开发周期
- 学习并使用github燃尽图的生成方式:http://radekstepan.com/burnchart/#!/ ,每日完成的Issue关闭,并当天用这个工具生成燃尽图
- 记录当天的任务分解和完成情况
- 昨天完成的事情1,2,3、今天要做的事情1,2,3、明天计划要做的事情1,2,,3
- 每个任务要明确写明指派给谁完成
- 记录产生的BUG列表,针对BUG分类,确定要修复的BUG进入Issue列表(所以燃尽图会是动态的):
- 已修复的BUG
- 不能重现的BUG
- 这个产品就是这样设计的,不是bug
- 没有能力修复,将来也不打算修复。
- 这个bug 的确应该修复, 但是没有资源在这个版本修复。 推到下一个版本。
- 如果BUG太多,进入BUG地狱模式,不能添加新功能,集中消灭BUG
- 每日10分钟(限定)的站立会议,成员的简要描述,突出记录遇到的困难,讨论解决方案,不要在站立会议上讨论繁杂技术细节
- 多人开发中,如果一个人修改的功能会影响到其他人,请学习并根据场景使用:
- 请求模式:你好,我能改动这个么
- 通知模式:xxx,我改了这个,你要更新下
- 多人开发中,如果一个人修改的功能会影响到其他人,请学习并根据场景使用:
- 发布冲刺博客,Project Manager根据上述内容对项目的进度、时间的压力、成员的状态、做出风险估计、并调整。
- alpha阶段进入扫尾阶段:
- 发布alpha阶段可用产品,版本号0.0.1,提供给10个早期用户试用,并收集反馈数据
- 如果是web项目,要发布到外网,提供给所有人试用
- 如果是app项目,请发布app包、例如android的apk
- 做感性分析、总结、吐槽
- 做理性事后诸葛亮分析,http://www.cnblogs.com/xinz/archive/2011/11/20/2256310.html
- 根据一开始确定的团队贡献分分配规则,根据每日记录的实际数据分配个人贡献分
- 发布alpha阶段可用产品,版本号0.0.1,提供给10个早期用户试用,并收集反馈数据
项目的小组互评(学生)
- alpha阶段就是用来暴露问题的,小组互评的内容可参考之前做过的案例分析,要体现专业水平
- 功能
- 功能使用上给其他组各找5个BUG,对BUG分类
- 每个组可以安排一周时间做BUG消灭,进入一个BUG地狱模式
- 评价其他组的功能实现和WBS分解文档之间的距离,再次理解WBS的作用,设计是一个需要反复练习、对比的过程
- 结合燃尽图,分析任务分解成Issue的合理性,燃尽图的任务分解和WBS能对得上么
- 使用四象分析法分析其他组功能类型,功能优先级是否适当
- 功能使用上给其他组各找5个BUG,对BUG分类
- 源码
- 评价其他组的源代码编码规范:
- 是否有编码规范,如果没有,为什么?
- 是否真正遵守了编码规范,如果没有,为什么?
- 评价其他组的源代码模块划分,模块划分是否和WBS相关,理解浅层的构架设计
- 模块和模块之间的接口有文档化么?接口设计应当遵循怎样的依据,什么是好的接口,什么是坏的接口。
- 跨进程、网络通信的协议是否有文档化么?是否可以并发开发
- 是否一个模块的改动,会频繁的要求另一个模块也跟着改动?是否符合开放封闭原则
- 对扩展开放
- 对修改封闭
- 评价其他组的源代码的测试质量
- 是否做好了界面和非界面逻辑之间的分离
- 在此基础上对核心稳定接口实现单元测试
- 评价其他组的源代码编码规范:
- 组织
- 评价其他组的耗时估计和冲刺过程之间的差距,为什么我们几乎总是会延期,延期是可消除的么?
- 评价其他组在任务分解到每个成员上的合理性
- 每个人是否有明确的角色,以及匹配角色的技能和过程?
- 组长是否有效照顾到了基础起点稍弱的成员?循序渐进为他分配合适的任务,为团队项目做贡献同时使其得到应有的成长?
- 功能
项目源码管理评价(助教)
- 基础:是否使用了源代码版本管理
- 基础:是否有良好的ReadMe,参考:https://github.com/dtrebilco/glintercept
- 基础:是否每个提交都有清晰的提交日志
- 基础:是否提交了不该提交的文件(bin、obj),使用.gitignore
- 基础: 是否有合理的文件夹结构:doc,src,test
- 基础:是否每日最后一个版本都是可编译运行的
- 中级: 是否有Issue列表,milestone
- 中级: 是否明确管理了每日Issue,关闭、新建
- 中级: 是否根据Issue列表自动绘制燃尽图,而非手工
- 高级:是否有效组织了git的分支,有效控制主干分支、开发分支、发布分支,使用pull-request方式
团队beta阶段开发
- Github建立beta这个milestone,添加新的Issue列表
- 冲刺报告环节各要素继续做
- 由于alpha阶段已经发布了版本,beta阶段可以每日发布一个可用的版本,版本号顺次递增,从0.0.1开始
- 从小模块开始,做好项目的构架梳理,做好界面和非UI模块的分离,针对非UI模块编写单元测试和功能测试
- 结合travis-ci.org自动化对项目的提交做编译、根据.travis.yml的配置自动运行测试脚本,组好持续集成,学习BVT知识,做好BVT
- 阮一峰:持续集成服务 Travis CI 教程
- 阮一峰的博客上写了大量的入门级教程,简单易懂,也可以学习。
- 阮一峰:持续集成服务 Travis CI 教程
- 每日使用
git tag 0.0.x
+git push origin 0.0.x
为当天的版本打一个tag,在Github的release标签下会自动打包该tag的源码 - 学习设计变更,项目功能是否有需要设计变更的地方?
- 燃尽图快完,项目进入稳定阶段
- 最后的测试、打包、进入发布阶段
附加作业
- 分数落后学生允许通过一定数量的附加作业争取及格,代码必须提交Github
参考
- http://www.cnblogs.com/xinz/archive/2011/11/27/2265425.html
- http://www.cnblogs.com/greyzeng/p/6044837.html
- http://www.cnblogs.com/15linzhijie/p/6105164.html
- http://www.cnblogs.com/SivilTaram/p/5656582.html
- http://www.cnblogs.com/younggift/p/6119550.html
- http://www.cnblogs.com/easteast/p/5854463.html
- http://www.cnblogs.com/schaepher/p/4933873.html
- http://www.cnblogs.com/math/p/git.html