小块工作的详细指南

121 阅读13分钟

虽然偶尔你会接到一个可以在几个小时内完成的任务,但你的大部分工作可能是由需要数天甚至数周才能完成的功能组成的。我发现,一项工作花的时间越长,我就越有可能失去进度,忘记下一步要做的功能的哪一部分,或者意识到我做的工作顺序不对,并因此而失去了时间。

无论新功能的构建有多容易或多难,花费的时间越长,将工作分解成可管理的步骤并确保你保持在最前面就越重要。你不可能把几周的工作都记在脑子里;花点时间预先计划一下你的工作会有回报,让你的头脑保持清醒,以便在功能上工作,并确保你在任何时候都能感觉到你的位置。

在这篇文章中,我将分享一些我发现的有用的策略,以帮助我在进行跨度为数周甚至数月的功能工作时制定计划并保持工作效率。

提前计划小步骤

当我开始做一个新的功能时,我会做的第一件事是创建一个新的文档(这可以是你喜欢的任何格式 - 我使用谷歌文档,但知道其他人总是使用笔和纸,这真的取决于你的个人喜好),并写下一个非常粗略的要点清单,列出所有我需要完成的不同工作,以考虑整个功能的完成。这个清单只是为了让我看,所以我不担心格式或结构,而是把它作为一种方式,把我能想到的所有需要做的事情,或考虑到的事情,都一股脑地写下来。我所做的大多数功能都有一个设计文件,其中列出了工作的范围和目标,所以我在创建清单时,会参考这个文件。

一旦我有了这个清单,我就可以开始对它进行排序,并决定哪些部分有必要优先处理。当决定从哪里开始时,我正在考虑以下问题。

  • 项目中是否有需要先完成的部分?先做某项工作是否能解开其他一切?
  • 该功能是否存在任何未知因素或风险?我是否需要先得到一些工作来验证这个方法?如果是的话,我想尽快解决这个问题,以避免以后的工作被浪费。
  • 是否有任何部分需要其他团队成员的帮助?如果是的话,我可能想尽快启动,这样我就会给我的同事一些通知,而不会强迫他们立即放下一切来帮助我。

这里的计划在很大程度上是一门艺术,而不是一门科学;即使我已经创建了我的优先级列表,但随着项目的进展,这个列表很可能会发生变化。你不是要创造一个完美的、僵硬的计划,你是要把一个粗略的计划从你的脑子里拿出来,写下来,这样你就可以跟踪你的进展,知道你接下来要做什么。

在工作进展中使用你的文件

一旦我投入到功能的工作中,我会定期回顾我的文档并进行修改。我还倾向于在文档中保留两个部分,一个是开放性问题,另一个是推迟的功能。

开放性问题

我使用文档的这一部分来跟踪我在工作中遇到的问题。我喜欢这样做,因为有时我不想暂停编码来问同事一个问题。我可以把问题写下来,然后继续我当前的工作。同时,我还可以把这个问题从我的头脑中卸载到文档中。我喜欢保持头脑清醒,以专注于当前的任务,而我发现唯一能做到这一点的方法就是把其他的东西都卸载到文档中。

递延功能和防止范围蠕变

就像任何大项目一样,一旦你开始工作,你将不可避免地发现有更多的工作要做,或者需要考虑削减的角落。这里没有规定你应该采取快速的黑客手段还是 "正确 "地解决问题,而采取哪种方式的答案在很大程度上取决于该功能的背景和手头的情况。

为了避免误入歧途,增加最初没有计划的功能,我会在我的文档中以 "推迟的功能 "为标题将它们记录下来。这意味着我保持专注于我的工作,但记下这个功能以便以后考虑,而且大多数时候我会询问同事的意见。如果我们决定这项工作是绝对需要的,我们就可以把它纳入当前的工作量中--同时也问自己,我们是否可以更好地计划,提前看到这项工作。如果这项工作很重要,但对当前的功能并不关键,我们会把它推迟到以后,在这种情况下,我们会在我们的错误跟踪系统中记录一个错误报告,描述这个功能,为什么我们认为需要它,以及为什么我们暂时推迟了这项工作。你可以在这里使用你或你的公司喜欢的任何工具。

我发现,明确说明你推迟的功能是避免范围蠕变的好方法,因为在任何时候你都考虑到了所有可能被添加到项目中的不同功能。当有人问起 "你考虑过添加X吗?"时,这也给了你弹药,因为你可以解释说你考虑过,但你推迟了工作,这里有解释你决定的bug报告/Trello卡/GitHub问题/JIRA票据/e.t.c的链接。

小步快跑,循序渐进地实施变革

一次性发布的大改动是有风险的。当你把它放到用户面前的时候,你一次性改变的越多,出现问题的风险就越大。一旦我得到了我的步骤清单,并且我把工作分解成更小的部分,我就会试着找出我是否可以在这些小步骤中部署我的变化。这不仅降低了风险,而且还有一个好处,那就是让你的代码更快得到同事的审查,并使你的同事能够一次性审查更少的代码行。想象一下两个开发人员,第一个人要求他们的同事审查他们花了一周时间写的200行代码,另一个人要求他们的同事审查他们花了三周时间写的3000行代码。你认为哪种代码审查会更彻底?

现在想象一下一个新功能的两种不同的部署策略:

  1. 第一种是一次性部署8周的工作,横跨数千行代码,一次性向所有用户开放新功能。
  2. 第二种是每周部署一到两百行的修改,在一个标志后面,使该功能可以快速打开/关闭。起初,它只为内部用户部署,当它接近竞争时,就会向一定比例的用户群推出,最后再对所有人打开。

第二种策略可以减少风险。你永远不可能消除风险,因为任何代码的改变,无论多么小,都是有风险的,但是通过一些计划和前期的思考,风险可以被控制在最低限度。定期对较小的改动进行代码审查也是非常有益的;我们将在代码审查一章中进一步讨论这个问题。

小步骤和git提交

在这些小步骤中工作也帮助我更好地以git提交的形式留下详细的工作痕迹。在我职业生涯的早期,我曾在一个功能上扎扎实实地工作了好几天,却没有做一次git提交,现在想想都觉得害怕。定期将你的工作提交到git(或任何类似的版本控制系统)有很多好处:如果你破坏了什么,你可以很容易地回到工作状态,你可以尝试一些事情,知道你可以很容易地撤销它们,你可以很容易地将你的工作推送到GitHub(或类似的),这样如果你的机器突然停止工作,它就有了备份。

我没有养成经常提交的习惯,其中一个原因是我不想花时间写详细的提交信息。当时我的公司会在合并前把所有的提交都压成一个,所以我不认为写大的提交信息有什么价值,这些信息会被压下来。当我意识到我可以做压扁的工作时,一切都改变了,我应该经常提交,这主要是为了我自己的利益

我现在的工作流程是,每当我达到一个自然的停止点时就提交,不管是修复一个小错误,还是完成构建一个功能的十步中的第一步,甚至是写一个失败的单元测试,我现在要做的就是把它变成绿色。如果我离开电脑几分钟去喝杯咖啡,你可以肯定我已经提交了我的工作。

因为当我的工作被合并到主分支时,它就被压缩成了一个提交,作为工作流程的一部分,我所做的频繁提交实际上只有我一个人看到。因此,我不需要写得很详细,我只需要写出对我有意义的提交即可。在我上传我的工作供代码审查之前,我可以重新建立基地并更新git历史。

如果我们拿一个典型的功能来说,我的本地git提交可能是这样的:

  • 编写失败的单元测试
  • 构建初始模块并实施someFunc
  • 添加基本功能的UI组件
  • 完善UI组件,解决边缘问题
  • 修复从API中获取数据的错误
  • 对CSS进行调整
  • 最后的单元测试和修复

请注意,我从来没有真正描述过我正在构建的实际高水平的功能。我不需要,因为那都是在我的脑海里!如果我需要更多的背景,我就会告诉你。如果我需要更多的背景,我有我的文件,在那里我列出了步骤,延迟的功能和任何开放的问题。

一旦我在本地完成了所有的工作,并准备好上传我的修改,我就可以重新建立这些提交。我重新归档,把它们压缩成一个大的提交,然后我会写一个全新的描述,可能看起来像这样。

Add column resizing to data-grid component

This commit adds the ability for the user to resize the columns of the data-grid
using their mouse. It will resize relative to the overall size of the data-grid,
and when resizing a column all other columns are left untouched.

If you're rendering a data-grid and don't want to allow the user to resize the
column, you can set the `no-resizing` attribute on the `data-grid` component.

The column resizing logic is also aware of hidden columns, and won't resize
those, and it will re-adjust the column widths if the container is resized. Once
a user has resized the column, it will never have it sized changed
automatically. If you want to programmatically reset a column, you can call
`resetColumnWidths()` on the data-grid instance.

You can find more info here:

- Design doc: https://...
- Tracking bug: https://...

现在,我花时间深入研究细节,写出一份详尽的工作描述(这也将构成我的拉动请求的描述,所以在这里最好能做到详尽,并留下大量的背景资料)。通过在最后这样做,我可以指出任何特殊的边缘情况或细微差别,任何其他开发人员可能想知道,我在历史上留下了良好的痕迹,为我或我的团队中的任何其他开发人员在未来的数据网格上工作。

对中断有弹性

在工作时,你会被一些事情打断,这是生活中的一个事实。在我写这篇文章的时候,我们大多数人都在家里工作,所以很多人更有可能被家人打扰,也有可能被同事在Slack上呼唤。我们都看到了这样的指导意见:软件开发人员应该避免被打断,以避免失去在工作时建立的心理环境,但不可能每天都不被打断。你的同事,非常合理地,会向你征求意见,你的老板可能想快速地聊点什么(希望是积极的东西!),或者,在我的例子中,狗会决定他们需要去散步了。

我仍然建议你尽量避免经常被打扰,这样你就有时间进入工作状态,我也会定期关闭我的工作聊天记录,关闭我的电子邮件,注销其他干扰,让我的头脑冷静下来,但对于那些你在工作过程中被打断的时候,我们在本章中讨论的小步骤工作将是非常有益的。你不会在一个巨大的变化中,你工作的整个产品被破坏了,而你脑子里有一个列表,上面有十个步骤,你需要完成这些步骤才能让它恢复工作。对我来说,现在的中断是 "给我五分钟的时间来完成",我把代码留在我可以再次拾起的状态,通常包括一个大的// TODO: jack, make this function... 类型的注释,我会拾起它。然后,我将添加并提交我的修改到git(字面意思是使用git commit -m 'WIP: step 4, add CSS' ,因为正如所讨论的那样,我将在以后重写它们),在这一点上,我已经把我的工作藏起来了,我已经准备好给我的同事/老板/狗全部的注意力。当你这样做的时候,至关重要的是,你要把你对当前工作的所有想法从你的头脑中卸下来,这样你就可以更容易地捡起。TODO 这可能是在代码中的评论,可能是在你的文档中,也可能是在便利贴上匆匆写下的。在哪里并不重要,但要把它们从你的脑子里拿出来。这可以让你的思想完全集中在现在需要你注意的事情上。

小块工作对我的生产力、我的心理健康以及我将任务卸载到文件(或纸张)上并专注于手头最相关的任务的能力非常有益。在过去12个多月主要在家工作的过程中,你发现了哪些有用的技巧和窍门?请在Twitter上与我联系,我很想听听你的建议。