文章作者: Vinta Software CEO Filipe Ximenes
原文链接: www.vintasoftware.com/blog/featur…
作为一家软件开发公司,我们一直致力于提高团队成熟度,这使我们在项目中采用更好的实践,例如站点可靠性工程和 DORA 指标的观察。
在许多项目中,问题不仅仅是技术层面的——而是首次提交之前的混乱。我们所说的“生产力不足”通常只是对需要做什么以及何时做缺乏清晰的认识。这就是为什么我们一直在讨论如何提高个人成熟度。换句话说,我们如何才能让开发人员在更短的时间内编写出更优秀的代码?
TDD、重构、解锁和调试——所有这些技巧都很有帮助。然而,说起来容易做起来难。因此,我们创建了一个分步指南,帮助专业人员将此功能开发流程无缝地融入到他们的日常工作中。
希望通过本指南,您能够更好地利用软件交付最佳实践来规划和编写功能。继续阅读,了解更多信息!
1. 了解该功能
首先,务必了解要做什么。仔细阅读整个功能用户故事,打开并阅读所有引用的外部文档(RFC、文档、代码片段等),检查图片,并研究设计素材。
如果是对现有功能的更改,请尝试一下,测试不同的参数和流程。如有必要,可以提出问题并标记利益相关者。如果无法等待答复,请尝试通过聊天通知相关人员或安排一次简短的会议。
如果你计划在冲刺阶段开发多个功能,请在开始开发其中一个功能之前,先为所有功能运行此步骤。这样做可以让你对任务有一个大致的了解,从而能够:
- 有时间收集故事中缺失的信息(并且异步地、不着急地进行);
- 优先考虑那些已准备好开发的故事,同时等待有关其他故事的更多背景信息;
- 更好地跟踪您的步伐并传达冲刺过程中的延迟。
2. 了解软件开发背景
每个功能都存在于更广泛的软件开发项目的背景下。如果您不了解某个功能需要与之交互的代码部分,就不可能规划如何实现该功能。
为此,请仔细阅读代码所在的整个流程,并确保了解每个部分的具体内容。此时,无需深入研究实现细节;只需阅读函数/方法名称即可大致了解流程。
例如,如果您正在开发一个序列化器,请从路由开始,阅读控制器和查询,然后阅读该序列化器中的所有代码。在您确信自己理解该功能和代码上下文之前,请不要继续进行下一步。
3. 制定解决方案
现在您已经了解了功能需求和相关的代码环境,是时候规划解决方案了。此时,请克制住立即开始编码的冲动。
相反,更深入地思考这个问题:
- 在纸上画图来形象化地展示你的方法;
- 映射实体关系和数据流;
- 勾画出不同组件如何组合在一起;
- 列出所有可能的情况和状态;
- 如果您需要更多上下文,请更仔细地检查现有代码。
一旦您有了初步的解决方案想法,请评估任何外部依赖关系:
库选择:
- 审查文档以确认所需的功能可用;
- 验证库在您的用例中的行为是否符合预期;
- 通过检查最近的提交和未解决的问题来检查库是否维护良好;
- 确认与您的应用程序的兼容性(语言版本、框架版本、许可证等);
解决方案分解:
- 将您的解决方案划分为更小、更易于管理的块;
- 将这些记录为您的主要任务中的子任务;
- 考虑边缘情况、异常、集成和验证;
- 识别可能受到影响的现有功能并添加测试子任务。
非功能性考虑:
- 评估可用性、性能、成本、数据完整性、可靠性、监控和可维护性;
- 如果您发现生产中存在潜在风险,请与您的技术主管 (TL) 合作评估影响并创建缓解子任务
规划的最后一部分实际上是最重要的部分之一:确定处理事项的优先顺序。为此,您需要评估每项活动的重要性和风险,并规划一个最小可行产品 (MVP)。
- 为了实现最大的价值,你需要完成哪些最少的工作/活动?哪些工作对这个功能至关重要?哪些工作不太重要,可以留到以后再做?以下是一些评估风险的技巧:
- 它是否耗时?这可能表明它需要根据重要性提高或降低优先级;
- 这会成为阻碍吗?同样,这可能意味着需要根据其重要性提高或降低优先级;
- 如果某项任务需要您熟悉部分代码或第三方库的经验,那么最好优先考虑它以避免后期阻碍;
- 零版本通常对界面的容忍度更高,除非用户体验对功能价值构成风险。例如,你不确定如何实现一个复杂的动画。
在运行此过程时,您经常会发现功能中有些部分过于复杂或耗时。当您注意到这一点时,请尝试想象一下,还有哪些类似的解决方案可以使事情变得更简单或更快捷。
4. 验证您的解决方案
对于更复杂的功能或者如果您对自己的解决方案没有信心,最好与其他人一起验证。
在大多数情况下,技术团队 (TL) 是审核的最佳人选,因为他们了解软件开发流程的技术背景。然而,有时也可以由经理、设计师或其他项目利益相关者来审核。
写一两段文字解释你计划如何实现该功能,包括部分(但不是全部)技术细节,然后发送去验证。如果无法用几段话概括,最好安排10分钟的桌面检查,以便让每个人都能更轻松地完成工作。
现在是汇报你注意到的复杂且耗时问题的好时机。与利益相关者确认你提出的更简单的解决方案是否真的有效。有时,完全删除该功能的一部分或将其推迟到其他时间也是合理的。
确保任何有用的延迟部分都被跟踪为具有适当上下文的新任务,以便稍后对其进行优先排序。
5. 让它发挥作用
现在是时候开始编写代码了。目前,请只关注你定义的 MVP。切勿超出范围,这一点非常重要。目标是创建一个可以验证你假设的可行原型。
编写尽可能少的代码非常重要——我们仍在学习新功能如何适应现有代码并验证我们最初设想的架构。
代码量更少意味着更容易尝试其他方法,并且如果我们最终不喜欢最初的方案,也可以更容易地修改架构。但是,在拥有一个可行的原型之前,不要轻易尝试其他架构。事实上,如果可行的话,可以考虑将第一个版本写成一个与应用程序完全解耦的脚本,然后再移植回来。
控制好工作节奏,不要操之过急。因为你已经规划好了执行计划,所以你可以逐一挑选你创建的最重要的子任务,并单独处理。一旦你选定了一项活动,就专注于完成它,其他任务就抛在脑后。
完成后,请编写提交消息并将子任务标记为已完成:庆祝进展非常重要!使用测试驱动开发 (TDD)(在实现功能之前编写测试)将使整个过程更加轻松,因为它遵循循序渐进、按节奏工作的理念。它还能帮助您构建一个全面的测试套件,这对下一步至关重要。
随着你的进步,你会识别出未映射的边缘情况和新的需求。重要的是,不要立即着手处理它们。首先,创建一个新的子任务,并将其列为优先级。这将使你不会偏离重点,减轻认知负担,并防止你感到焦虑。
6. 重构的时间
有了第一个可运行的版本,现在是时候致力于代码质量并为最终解决方案做好准备了。
此时,您不应添加任何新功能。尝试您认为更适合问题的架构,重新组织接口,重命名变量,隔离关注点,封装实现细节,并确保代码清晰易懂。
因为您已经编写了测试,所以您可以确信迄今为止所做的工作是有效的,并且不会破坏其他功能。由于您只拥有该功能的基本框架,因此重构所需的工作量应该很小。一旦您对代码的架构和质量感到满意,就可以继续下一步了。
Vinta 联合创始人在其著作《战略工程软件》中更深入地阐述了整个过程,并探讨了技术团队如何在不依赖职位或层级的情况下改进软件交付方式。一书的内容。
7. 填补空白
现在是时候完成功能了。处理那些你认为不重要的项目。完善细节、锦上添花的功能,并完善界面。保持节奏,一次完成一项任务,使用测试驱动开发 (TDD),并通过提交代码并将子任务标记为完成来庆祝进度。
检查代码并检查是否应该添加日志消息,或者某些部分是否会因更多的代码注释而受益。
8. 更新并创建文档
好了,现在让我们通过查看需要更新的文档并创建新的文档来结束此功能。您还应该考虑编写一份ADR(架构决策记录)来跟踪变更,并同步给团队成员。
总结
在 Vinta,在我们的软件开发项目中实施这个分步指南已经取得了卓越的成果和积极的团队反馈。
对于经验丰富的开发者来说,这个框架很可能直观地规范化您现有的工作,但它仍然可以作为宝贵的定期检查点,确保您遵循最佳实践。对于其他经验水平的开发者,我们建议系统地遵循此功能开发流程指南来开发每个新功能,直到该流程成为您的第二天性。
将这些实践融入到你的开发工作流程中,你不仅可以编写出更优质的代码,还能为构建更成熟、更可靠的工程文化做出贡献。今天对合理规划和结构化开发的投资,将在未来带来回报,减少技术债务,打造更具可持续性的项目。