创造历史:撰写需要撰写的文档

创造历史:撰写需要撰写的文档

原文:https://medium.com/hackernoon/making-history-writing-the-docs-that-need-to-be-written-1396e27fae65

在这篇博文中,我想谈谈文档的问题,为什么我们为我们的项目制作一个好的文档体是重要的,不管是开源项目还是私有项目。

为了促进我们和同事的职业发展,我们能做的最重要的事情之一就是学会分享我们的知识。最直接的方法之一就是写下来。记录我们的代码,解释当我们实现一个新特性、修复一个 bug,或者决定在我们的项目中加入一个新的库或工具时,为什么我们要做出某些折衷。

有时候很难知道要记录什么。同样,我们需要优先考虑我们实现的特性,或者我们首先修复的错误,我们也需要优先考虑我们写的文档。我们可以通过询问关于我们的项目或者我们正在处理的当前问题来解决这个问题,然后尝试用文档来回答它们。

社会以书面形式收集他们的知识,使之成为历史,这是有原因的。口头传统被遗忘了。

下面我添加了一些我们应该问的关于我们项目的问题,其中大部分来自我作为 RabbitMQ 核心开发人员的时候。我还提供了一些示例答案。

Photo credit: https://flic.kr/p/944A8a

以下是问题,排名不分先后。

为什么我们要使用非标准的语言特性?

在 RabbitMQ 中,我们使用了自己的 logger 实现,而 Erlang 已经提供了一个。为什么?该语言提供的一个使旋转日志变得困难。使用我们自己的 有什么问题吗?。当一个改变日志 API 的新 Erlang 版本出现时,RabbitMQ 日志会崩溃。

为什么我们选择一个库而不是一个解决同样问题的竞争对手?

这是 RabbitMQ 的另一个例子。代理曾经用 Make 实现了一个构建基础设施。它有点麻烦,文档很少,很难扩展。而且,它是自制的,而 Erlang 至少有两个众所周知的构建工具: rebarerlang.mk 。虽然 rebar 可能是 Erlang 社区中最受欢迎的,但我们还是选择了 erlang.mk。为什么呢?我们现有的构建工具已经在使用 Make,并且有很多特性。我们用它来建造。deb 包,。rpm 包、OS X 自带的 tarballs、Windows 版本、运行测试、编译代理、编译 RabbitMQ 插件、来自 Git/Mercurial 的依赖管理等等。我们不想把所有这些功能都移植到 rebar 上。额外的收获是,erlang.mk 的作者当时正和我们一起工作,所以总的来说,erlang.mk 看起来像是构建工具的正确选择。

为什么我们要重新实现一个现有的特性?

我在 RabbitMQ 的任务之一是重新实现队列持久层的一部分。为什么?首先,当消息开始在队列中堆积时,RabbitMQ 会变慢并被阻塞一段时间。是的,RabbitMQ 在不得不排队事情的时候非常慢(这一次讽刺意味很浓)。在运行了几个基准测试并经历了几个调试会话之后,我设法确定了消息如何被保存到文件系统的问题。所以,我不得不重新实现一些逻辑。这整个问题导致了懒惰队列的产生。

为什么不能实现特性 X?

在 RabbitMQ 中,许多特性无法实现,因为 AMQP 限制了代理的能力。它规定了应该对消息做什么,应该如何遍历代理的内部部分,何时以及如何根据发布者设置的属性丢弃消息,以及订阅队列时消费者设置的约束,等等。

长话短说,总有权衡。

有时候你不需要像 AMQP 那样遵守协议,但是你有时间限制,或者经济限制。也许法律不允许你从你的用户那里收集数据(有很好的理由),或者你的团队中没有足够的开发人员能够在新特性被部署到产品中后维护它。我相信你可以根据自己的工作提出更多的例子。长话短说,总有权衡。

当然,还会有更多类似的问题。上面提到的只是我在 RabbitMQ 工作时的一些例子。

确保每个人都知道这些文件

一旦我们有了文档,我们必须确保我们的同事知道文档的存在。你不会想写东西,所以它会在公司的维基上庄严地死去。

我试着给团队发电子邮件,附上新文档的链接,但我认为这还不够。更好的办法是向我们的团队做一个演示,解释我们是如何实现新功能的。当然,我们不能对项目中的每个新功能都进行技术讨论,但也许我们可以习惯于对主要功能进行讨论。我给你举个例子。

当我致力于修复 RabbitMQ 队列的性能问题时,我试图确保团队中的每个人都知道我在做什么。我试图解释我在调试问题时所面临的问题,后来,一旦我确定下来,我试图向团队中的每个人解释我们当时的队列实现是怎么回事。后来,我制作了一对文档解释 RabbitMQ 队列的内部工作方式。除了让每个人都知道 RabbitMQ 内部是如何工作的,我们的目标也是确保我们不会再犯同样的错误。

结对编程不就是为了这个吗?

你可能会问,我们是否可以通过结对编程来解决这个沟通问题。我不这么认为。我不认为结对编程是这里的正确答案。社会以书面形式收集他们的知识,使之成为历史,这是有原因的。口头传统被遗忘了。此外,我们需要一个超越小型团队的解决方案,它也适用于远程团队。结对编程对于分享想法和一起想出解决方案是很棒的,但是必须有一种方法来巩固结对编程会话中获得的知识。这就是文档和技术会谈的目的。

不是每个人都是考古学家

拥有好文档的另一个原因是,不是每个人都是代码考古学家。我们不能让每一个 bug 都成为我们代码的考古学研究项目,无论谁被分配到这张票,都必须通过提交的历史来理解为什么错误的代码行首先会出现在那里。

我们不能让每个 bug 都成为我们代码考古学中的一个研究项目,无论谁被分配到这个项目,都必须通过提交的历史来理解为什么错误的代码行会在第一时间出现。

我们可以从 RabbitMQ 中再举一个例子。由于性能原因,RabbitMQ 在 AMQP 停止了对立即标志的支持,但是 RabbitMQ 应该是 AMQP 的忠实实现,对吗?嗯,也许在一个完美的世界里这是真的,图灵机有无限的磁带,网络分区不会发生,但在我们的世界里我们必须做出权衡。为了能够交付一个产品,商业目标将会被妥协。用户故事将被拆分。计划中的功能将被丢弃。如果可能的话,我们需要一个地方把这些都记录下来。请记住,团队成员会改变,项目经理会来来去去,我们不能一遍又一遍地讨论为什么需要特性 X,然后意识到它无法实现。

想想 children^w 的新员工

写文档的另一个好理由是,我们的团队迟早会有新人加入。我们希望让这些新成员的入职尽可能顺利。我们不希望他们走来走去,试图找出构建项目的正确编译器标志,或者他们在哪里可以找到能够将项目部署到生产环境的凭证。

远程同事呢

无论您是在一家开源公司工作,还是为一个私人项目工作,都可能有远程人员参与项目。这些人甚至可能和我们处在完全不同的时区。我们不能假装当其他人在工作时,整个团队都可以回答问题。因此,对于这类项目来说,拥有易于访问的文档是必不可少的。此外,即使你没有远程同事,人们仍然会休假,生病,或者只是因为任何原因无法回答问题。所以,请写那些文件。

不再有战争英雄

最后,我想谈一谈在软件行业根深蒂固的英雄文化。我认为我们过于看重那些过去不得不处理糟糕架构的人的经验。我们认为他们的战斗伤痕非常珍贵,值得尊敬。

生产事故应该教会我们尊重同事,理解他们下班后的时间和我们一样宝贵

不一定要那样。我们可以尝试建立一种文化,使从这些事件中学习的行为系统化,这样新成员就知道发生了什么,如果他们实施这个和那个会发生什么,而不会遭受这么多的创伤。是的,他们仍然需要在某个周五晚上接受洗礼,因为缓存机已经失控,而其他人都在享受周末的开始。这些事件教会我们尊重好的实践,并理解它们的存在是有原因的。他们还应该教会我们尊重同事,明白他们下班后的时间和我们一样宝贵。因为有人得到了额外的报酬来随叫随到,这并不意味着我不必关注我投入生产的代码。

乐章结尾部

如果你修复了一个硬错误,我希望你向每个人解释,所以我们从经验中学习,我们学习系统如何工作,我们学习如何调试东西,我们学习在修复错误时什么可行,什么不可行。人们还将学会理解以正确的方式解决问题需要时间。我们所做的不是微不足道的。如果我们跳过所有这些步骤,我们会让未来的自己变得更加困难。

如果当我们离开一个团队时,我们拥有其他人没有的项目知识,那么这就是失败。让我们共同努力防止这种情况发生。

黑客中午是黑客如何开始他们的下午。我们是 @AMI 家庭的一员。我们现在接受投稿并乐意讨论广告&赞助机会。

如果你喜欢这个故事,我们推荐你阅读我们的最新科技故事趋势科技故事。直到下一次,不要把世界的现实想当然!


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除