[知识路书]事后分析
设想和目标
Q
- 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述?
- 我们达到目标了么(原计划的功能做到了几个? 按照原计划交付时间交付了么? 原计划达到的用户数量达到了么?)
- 和上一个阶段相比,团队软件工程的质量提高了么? 在什么地方有提高,具体提高了多少,如何衡量的?
- 用户量, 用户对重要功能的接受程度和我们事先的预想一致么? 我们离目标更近了么?
有什么经验教训? 如果历史重来一遍, 我们会做什么改进?
参考我们的选题博客,我们希望解决“文献梳理、呈现与展示没有直观形式”这个问题,希望能够围绕学术阅读中的需求,以知识导图为主要形式,实现一款集文献管理与内容呈现于一体的软件。由于这个概念略显新颖,定义并不是十分精准明确,可能随着迭代演进产生细微调整,但大的方向不会改变。
我们对典型用户和场景有较为清晰的描述分析,可以参考我们的功能规格书,主攻科研群体,细微提供小而美的服务。
就alpha结果来看,我们实现了初期制定的所有功能需求,根据实际需要又额外实现了用户权限系统、路书分享外链、bibtxt批量导入等功能,同时定制了路书编辑器,对界面及布局也做了一定程度的美化。我们收到的用户反馈绝大多数都是4分及以上的积极评价。总的来说,从完成度、美观度、用户满意度来看,我们都认为切实达到了本阶段的开发目标。唯一的遗憾是我们的用户数量没有达到预期的100人,我们已经讨论分析了推广策略、推广渠道等存在的问题,并有希望在下一步的推广中更快速增添用户量
我们目前的工程质量虽然不是完美的,但完全处于可控范围内,这主要得益于我们较为合理的协作方式和开发流程,允许我们更从容地管理工程。下一步我们会进一步强调代码质量,尤其是命名规划与必要性注释。
用户对于功能的反馈可以查看我们的项目展示博客,总的来说我们关注的特性大多也是用户关注的,如文献批量添加、界面美观、用户引导等。期待后续在解决用户提出的问题后我们能收到更多正向反馈
计划
Q
- 是否有充足的时间来做计划?
- 团队在计划阶段是如何解决同事们对于计划的不同意见的?
- 你原计划的工作是否最后都做完了? 如果有没做完的,为什么?
- 有没有发现你做了一些事后看来没必要或没多大价值的事?
- 是否每一项任务都有清楚定义和衡量的交付件?
- 是否项目的整个过程都按照计划进行,项目出了什么意外?有什么风险是当时没有估计到的,为什么没有估计到?
- 在计划中有没有留下缓冲区,缓冲区有作用么?
- 将来的计划会做什么修改?(例如:缓冲区的定义,加班)
我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
总的来说我们还是有相当充足的时间进行计划与规划的。实际上开发初期大家的主要工作就是学习开发技术并作一些开发计划。当然,计划永远赶不上变化,所以我认为我们的一大优势就是可以不间断地调整计划、补充计划从而适应变化,这得益于我们强调开发人员“可替代性”与“不可替代性”权衡的协作节奏。我想,这也是敏捷开发的哲学内含,以不断的变化来应对快节奏的开发与交付
我们的不同意见大多可以在同步会中解决,一方面是因为团队气氛自由融洽,大家可以很好地表达自己的观点、参考别人的观点,因此分歧总能快速消除。实际上这或许也是前段时间三明治交流法的实践结果。我观察到大家在对待异见时总能先总结对方的优点,再指出其不足,并给出自己的解决方案————这样的沟通理性而容易达成组内共识
原计划的工作全部完成,并额外完成了一些工作,可以参考上一节。唯一遗憾的是我们一直受限于资源与政策,没有解决部署域名的问题,或许下个阶段我们能找到一些免费的解决方案,或替代方案。
总的来说我们的每一项工作都是有意义的,开发节奏紧凑充实。唯一(看起来)没什么价值的工作是给全体组员开了个超级用户账号,最后发现大家大部分时候还是用自己的(普通用户权限)账号密码登进去做测试……(主要因为我们几乎不需要手动修改生产环境的数据,这其实是个好现象)
分发的每一个任务都会在开会时清楚定义,并在issue中描述要点。但衡量标准往往是不固定的,因为我们希望组员根据自己的实际开发情况与个人理解决定手头正在开发的功能需要实现到什么程度(当然后端开发,尤其是测试,是有非常明确的验收指标的,比如后端的两位同学很辛苦地把覆盖率拉到了100%),背后的思想是:司令部把指挥权交给战地指挥官往往是合理的。
项目整体按计划进行,意外大多来自第三方组件。比如我们调研到的一款markdown渲染插件,它的实现有一些问题,传入slot中的内容没有实现数据双向绑定,数据更新后必须重新挂载渲染组件才能刷新————这是我们意料外的,并且有些反直觉而难以排查。所以花费了额外的精力去定位、修复这个错误。
我们使用了测试-生产双分支的形式管理代码仓库,这实际上就是一种缓冲机制。
资源
- 我们有足够的资源来完成各项任务么?
学习资源:
- 非常充足。
- 无论是前端的 Vue.js,还是后端的 Django,网上的学习资料都十分丰富。
- 同时,本组有资深开发人士,能提供足够的技术支持。
人员配置:
- 较为充足。
- 4 人负责前端,2 人负责后端,1 人机动。
硬件资源:
- 匮乏。
- 自己的服务器性能较差。
- 缺少可使用的域名资源。
- 各项任务所需的时间和其他资源是如何估计的,精度如何?
在每次的任务发布之前,通过例会进行任务拆解,分发到个人头上。
每个人领取 issue,将分解任务的时间资源按小时级别估计,需求任务的时间资源按天级别估计。
估计在大部分时间是比较精准的,但是由于某些不可抗力的干扰,偶尔会出现估计错误。
- 测试的时间,人力和软件/硬件资源是否足够? 对于那些不需要编程的资源 (美工设计/文案)是否低估难度?
足够。
后端组 2 人负责测试工作。分别从 CURD、Permission 和 Auth 三个方面进行测试工作。
关于美工设计与文案方面,美工设计方面的难度不是很大,但是我们对文案的重视程度有一定不足,后期需要补充。
- 你有没有感到你做的事情可以让别人来做(更有效率)?
没有。我们组强调每个开发者专精一个方向(不可替代性)并熟悉其他人的开发方向(可替代性),从前者的角度来看,我做的事情由我来完成是效率最高的。
有什么经验教训? 如果历史重来一遍, 我们会做什么改进?
由于经验不足,错误类型的接口定义和错误处理方式小组成员未做统一约定,导致错误提醒内容存在差异和错误。
由于对后端文献数据内容形式的不了解,以及文献表格显示哪些内容也不清晰。我们文献管理的table以及创建文献的drawer的相关字段设计混杂,不够人性化,table和drawer之间字段也有冲突。
改进:在和PM以及相关负责同学协商,充分考虑用户需求后,进行相关字段的设计和重构。
变更管理
Q
- 每个相关的员工都及时知道了变更的消息?
是的,我们采用GitHub上的项目管理相关功能来保证队友及时了解变更代码或者消息。
- 在每次dev代码更新之后,都可以了解更新的内容和时间,git自带的拉取功能也能随时确保自己的代码是最新的。
- 团队采用issue和解决issue的开发模式,每个issue合理分配给不同的队友,我们在接收到issue之后,会收到GitHub的邮件,保证任务分发和出现突发变更的时候,3. 每个队友都能及时知晓。
周期性的大组会和随时的小范围会议,保证了每个成员都能了解项目的进度与方向的变更。而且每个成员的问题都能随时得到解决。
- 我们采用了什么办法决定“推迟”和“必须实现”的功能?
我们在项目最初设计文档时,确定了必须功能和附加功能,所以在面对具体功能的规划时,可以参考 最初设计文档的功能规划,来决定这一项功能时必须按时完成的核心功能还是可以推迟的提升功能。
- 项目的出口条件(Exit Criteria – 什么叫“做好了”)有清晰的定义么?
有,出口条件也是在最初的设计文档中确定了的。在设计文档中,除了确定必须功能和附加功能外,也确定了𝝰阶段和𝝱阶段的可发布的几大核心功能。
同时,从测试和debug的角度出发,出口在满足核心功能的同时,也需要整体代码有90%以上的测试覆盖率,以及前端代码审核后交付且新手可流畅使用。
- 对于可能的变更是否能制定应急计划?
可以。
我们面对代码上可能的变更,可以及时发布新的issue,其中可以设计各种label比如优先级程度、是否是bug、是否是核心功能,并分配个一个人或者多人来完成。
在大的代码思路上可能出现的变更,我们有密集的大小组会,可以随时统一思想,并且集思广益理清思路、解决问题。
- 员工是否能够有效地处理意料之外的工作请求?
是。
我们团队采用网状式扁平化的团队开发方案,每个队友都有各自最擅长的开发方向,而且也通过组会交流对其他人的开发代码比较了解,能够处理自身开发代码之外的功能需求,并且可适应跨功能的开发。
而且,整体队友的开发积极性高。能够在完成基本功能的基础上,发动自己的主观能动性,开发提高功能,并且自己思考打磨各自的模块,开发主动性高,可以有效处理意料之外的工作请求。
我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
我们学到了软件工程的团队开发的方法。比如基于GitHub的代码管理,团队会议组织方法,面对变更的群策群力,等等。
如果历史重来一次,我们会做:
- 在初期需求分析的学习阶段,每天请同学进行学习交流,进行知识交流,并同步组内的学习进度。
- 设定开发每个时间分段的任务和人员安排,让开发更有节奏,让每个队友也知道自己的进度安排。
- 提前推广,更早的知道用户的反馈,辅助后续开发。
设计/实现
Q
- 设计工作在什么时候,由谁来完成的?是合适的时间,合适的人么?
在我们团队的敏捷开发过程中,不同层面的设计工作其实贯穿了整个流程。初期时,设计工作关注功能,在撰写产品功能说明书时,我们侧重从用户使用角度去设计产品的目标和功能;而在实际开发时,我们侧重从技术角度设计整个软件框架、工程维护规则、界面风格规范、错误处理规范、axios请求规范等;而到alpha阶段接近完成时,随着测试和使用反馈,又进入了新一论的设计和实现过程。
我们认为团队在参与设计的时间是合适的,正如《构建之法》在介绍设计、编码、测试等内容在敏捷开发的流程时的图示,每一部分并不是完全割裂的,而是此消彼长式地相互融合。
对于功能设计和工程实现设计,我们主要交由本组开发经验丰富的hdl和zwx同学完成。后期分析,我们认为这样的设置是合理的,避免团队设计不切实际的目标或走过多的弯路,同时也有助于其他组员学习。
- 设计工作有没有碰到模棱两可的情况,团队是如何解决的?
在没有编码实现或编码实现初期时遇到过模棱两可的情况,例如前端向后端的请求接口设计在没有实现情况下很难做到完备地考虑。
解决思路:构建一个基础的设计先行实现,并能够在demo环境下完成功能。而后在scrum例会时,向组员讲解清楚功能实现,由团队共同协商再提出新的具体优化内容,由此产生迭代的过程,最后达到满意的结果。
- 团队是否运用单元测试(unit test),测试驱动的开发(TDD)、UML, 或者其他工具来帮助设计和实现?这些工具有效么? 比较项目开始的 UML 文档和现在的状态有什么区别?这些区别如何产生的?是否要更新 UML 文档?
团队针对后端使用了单元测试,并检验了代码覆盖率。
- 什么功能产生的Bug最多,为什么?在发布之后发现了什么重要的bug? 为什么我们在设计/开发的时候没有想到这些情况?
整体上项目的Bug分布比较均匀,在各处均有产生。在修复问题时,遇到问题比较多是脑图MindMap组件的定制,主要涉及到了css风格自定义以及传统js&vue的编程,因此比较困难。
在实现时,我们采用了release/dev双分支的设计,所有的pull request均合并到dev分支,待检验完毕后合并至release分支,在每个版本发布前均会进行测试,因此分布版本未遇到什么重要的bug。对于小问题,发布后曾出现了页面跳转错误的情况,事后分析是由于vue.router部分调用方式不遵循解耦思想,在Beta阶段时,需要规范组员在路由器跳转、错误处理、axios请求调用接口上的使用规范。
- 代码复审(Code Review)是如何进行的,是否严格执行了代码规范?
Code Review 借助 Github 的 Pull Request 和 Issue 功能实现,所有的pr要求必须有一名组员同意,github会根据近期的编码历史,向pr发起者推荐合适的reviewer。
代码规范:我们团队并没有自行定义一套完整规范,而是使用了代码规范ESLint+WebStorm风格检查代码的规范。经过组员反馈,对两套规则下的代码复审和阅读持好评。
对于团队大部分组员来说,这是我们第一次基于Github合作完成工程项目,在流程上,我们体验了软件开发一个周期中的设计、实现、测试的流程,在内容上,具体了解了Web开发的技术,在合作技术上,基本掌握了基于Github的项目推进和团队合作方法。
如果历史重来一边,我们会改进的地方有:
- 明确Issue和Pr的规范和格式。
- 测试更早时间介入。
我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
测试/发布
Q
- 团队是否有一个测试计划?为什么没有?
有测试计划
- 是否进行了正式的验收测试?
是, 在正式发布前, 我们寻找了目标用户, 让目标用户在软件的环境中使用了一段时间, 在未知用户操作的情况下, 让用户能够接受软件。
- 团队是否有测试工具来帮助测试?
测试工具主要使用django rest test和coverage, 通过django rest test对后端的CURD, 鉴权, 用户注册等操作进行正确性验证, 利用coverage工具对django测试的代码覆盖率进行检查, 如果添加新功能后, 代码覆盖率没到100%, 那么继续添加测试。 前端主要是使用场景测试, 在前端web app的几个主要的界面和路书的功能场景内进行测试。
- 团队是如何测量并跟踪软件的效能的?从软件实际运行的结果来看,这些测试工作有用么?应该有哪些改进?
测试工具对于前后端的验证有作用, 之后需要对前端添加更多自动测试。
- 在发布的过程中发现了哪些意外问题?
我们学到了什么? 如果重来一遍, 我们会做什么改进?
我们需要添加功能后进行更细节的测试, 使用CI CD工具进行回归测试。 在beta阶段, 我们会添加更多功能, 在之后的开发中, 需要不断完善测试, 如果再来一遍, 我们会更早使用TDD(测试驱动开发)。
团队的角色,管理,合作
Q
- 团队的每个角色是如何确定的,是不是人尽其才?
- 团队成员之间有互相帮助么?
- 当出现项目管理、合作方面的问题时,团队成员如何解决问题?
团队角色是第一次开发会上划分的,由于大家基本都没有相关经验,只是凭借兴趣选择方向。大家开发积极性都很高,再加上我们的任务的动态调整机制,总的来说是人尽其才的
相互帮助是肯定存在的,我们的协作中穿插了大量结对编程与小范围会议,不乏互相帮助的过程。我们也通过这种形式解决了大部分合作问题,余下的难题留给同步会与集中开发。
- 每个成员明确公开地表示对成员帮助的感谢 (并且写在各自的博客里):
我感谢 _______<姓名>______对我的帮助, 因为某个具体的事情: _____________________。
总结:
你觉得团队目前的状态属于 CMM/CMMI 中的哪个档次?
你觉得团队目前处于 萌芽/磨合/规范/创造 阶段的哪一个阶段?
你觉得团队在这个里程碑相比前一个里程碑有什么改进?
你觉得目前最需要改进的一个方面是什么?
对照敏捷开发的原则, 你觉得你们小组做得最好的是哪几个原则? 请列出具体的事例。
正如我们前面提到的, 软件的质量 = 程序的质量 + 软件工程的质量,那团队在下一阶段应该如何提高软件工程的质量呢?
团队阶段介于“规范”与“创造”之间
最需要改进的是代码质量管理
做的最好的是:学习全部经验
在程序质量上,我们会引入更多测试与错误处理相关的机制,借助自动化手段将劳动力解放并确保质量。这或许可以借助Github Action实现
在工程质量上,我们会紧抓代码质量管理,重构一小部分有“坏味道”的代码,更注意规范命名、注释与项目结构管理,写出更可读、可维护的代码
- 代码管理的质量具体应该如何提高? 代码复审和代码规范的质量应该如何提高?
目前的复审形式良好,前期出于“快速实现”的思想并没有十分严格要求代码规范,后续提升过审标准即可。这需要一次同步会议进行全组范围内的规范与说明
- 整个程序的架构如何具体提高? 如何通过重构等方法提高质量,如何衡量质量的提高?
整体架构良好。前端追求更扁平的页面/组件嵌套逻辑,并将常用操作集抽象为工具函数。后端已经借助插件框架实现了比较好的工程结构
- 其它软件工具的应用,应该如何提高?
TODO
- 项目管理有哪些具体的提高?
暂无,目前管理流程运作流畅,维持现状即可
- 项目跟踪用户数据方面,计划要提高什么地方?例如你们是如何知道每日/周活跃用户等数据的?
由于未成规模,暂时没有相关统计。后续我们考虑引入一些第三方BaaS服务统计DAU等指标
- 项目文档的质量如何提高?
- 对于人的领导和管理, 有什么具体可以改进的地方? 请看《构建之法》关于PM、绩效考核的章节, 或者 《人件》等参考书
- 对于软件工程的理论,规律有什么心得体会或不同意见? 请看阅读作业。 (这个作业的期中阅读)
讨论截图
关于后续如何重构/改进代码质量的问题,组员积极讨论:
Q: 对比敏捷的原则,你觉得你们小组做得最好的是什么?
Q: 什么是在下个阶段要改进的地方?越具体越好。