开发人员的技术写作

发布时间 2023-07-27 21:44:29作者: chuckQu

HTML、CSS、JavaScript、Python、PHP、C++、Dart--有这么多的编程语言,你甚至可能完全精通其中的几种。但是,随着我们的目标是写出更多、更好的代码,我们用日常语言写作和交流的方式变得越来越重要......甚至可能被忽略了。

我们编写和讨论代码的方式可以说与代码本身同样重要。尽管你可能在这个问题上持不同观点,但我们都可以同意,我们的言辞既会提高代码的有效性,也会损害代码的有效性。

在这篇文章中,我想概述一下这两个看似截然不同的领域--编程和写作--如何能够结合起来,将我们的开发技能提升到一个新的水平。

等等,技术写作?是的你没看错。我真的相信我们在某种意义上都是作家。我会在这里给你介绍写作技巧、建议以及例子,使你成为更好的开发者和沟通者。

本文包括以下部分:

  • 技术写作无处不在
  • 什么才是好语法?
  • 编写代码注释
  • 编写pull request
  • 报告bug
  • 与客户沟通
  • 编写微文案
  • 编写无障碍标记
  • 总结

技术写作无处不在

2021年,流行的Mac Git客户端Tower背后的团队对4000多名开发者进行了调查,发现他们中近50%的人每天花3-6个小时来编写代码。

image.png

是的,这是一个针对特定小众群体的调查,但我想我们中的很多人都在这个范围内。无论如何,开发者并非7 * 24都在编写代码,因为正如这个调查所显示的,我们花了很多时间在做其他事情。

这可能包括以下事情:

  • 演示一个新功能,
  • 记录这个新功能,
  • 更新与这个新功能相关的工作计划,或者
  • 将支持这个新功能的工作积压。

当然,总是有时间上厕所和玩Wordle游戏的。

无论如何,我们通常所做的大部分事情都涉及与团队、同事、客户、用户以及其他开发者等人沟通。

所以我们确实花了很多时间通过文字与人类交流,除了通过代码与计算机交流之外。文字是书面语言。如果我们能更好地书写文字,我们就能更好地交流。当我们更好地交流时,我们就更有可能得到我们想要的。

image.png

而且这还不是全部。一些程序员还喜欢制作他们自己的产品,这意味着他们需要将市场营销作为工作的一部分。技术写作在这方面也起着重要作用。所以没错,我可以非常公正地说,技术写作确实无处不在。

什么才是好语法?

有这么多的编程语言,我们最不想做的就是学习另一种语言。

语法是英语的一个重要组成部分,它释放了沟通的全部潜力。它使我们更加正式、专业和连贯。

让我给你简要介绍一下语言。

英语语法

正如编程语言,英语有一个明确的语法,它从单词开始。

单词是英语的组成部分,它们可分为八个类别:

image.png

  • 名词(Nouns)。这些可以是人名、动物、地点、概念和物体的名称。

    • CSS 是前端开发的核心语言之一。
  • 动词(Verbs)。动词传达动作。即使“is”也可以被视为一种动作。

    • 玛西娅早上编写代码,下午回复电子邮件。
  • 形容词(Adjectives)。形容词是我们描述名词的方式。它们就像元数据,为句子增添更多细节,描绘出生动的画面。

    • CSS是一种优雅富有诗意的语言。
    • HTML表格是复杂繁琐的。
    • 盒模型对于理解CSS很重要
  • 介词(Prepositions)。介词在名词和其他单词之间建立关系,通常表示方向、时间、地点和空间。

    • 你将你的工作提交仓库了吗?
    • 对于这个组件,最好的方法是什么?
    • 我们真实用户进行了访谈。
  • 副词(Adverbs)。有时候需要更具体的动作描述,因此我们使用副词,比如“跑得”和“编译”。它们通常以“-ly”结尾。

    • 绝对是所有想法中最好的。
    • 奇普耐心地等待戴尔的反馈。
    • 团队在项目上勤奋地工作。
  • 连词(Conjunctions)。连词连接句子中的短语。

    • CSS用于样式设计,HTML用于标记。
    • 是的,我编写代码,我也从事设计工作。
    • 那修复了这个漏洞。然而它又引入了一个新的漏洞。
  • 过渡词(Transitions)。段落由相互连接的句子组成,这些句子使用过渡词来连接。

    • 有很多编程语言。然而,只有少数被应用于网络行业。
    • 首先,克隆该目录。
    • 我喜欢这种方法,但另一方面,我也知道另一种方法。
  • 代词(Pronouns)。当名词重复出现时,我们会用代词来代替,比如“他”,“它”和“那个”。

    • CSS是一种样式表语言。我们使用来为网站添加样式。
    • 托尼热爱编码,每天练习。
    • 我们的客户精通技术,因为他们了解代码。

将这些语言元素看作UI组件:它们是模块化的部分,你可以移动它们以构建完整而健壮的句子,就像你可能会组装完整而健壮的UI一样。所有组件是否始终需要存在?当然不需要!使用所需的部分组装句子,就像你使用界面一样来完成体验。

语气和语调

词汇、标点符号、句子结构和单词选择。这些都是英语的组成要素。我们用它们来分享想法,与朋友和家人交流,并给同事发送电子邮件。

但考虑我们信息的声音是至关重要的。一个感叹号就能完全改变信息的语气,这很神奇:

  1. 我喜欢编程。
  2. 我喜欢编程!?

我们很容易把语气和语调混淆,反之亦然。

语气关乎我们单词选择的问题,这取决于上下文。例如,针对初学者的教程更有可能使用俚语和非正式的语言来传达友好的语气,而文档可能以正式、严肃和专业的方式撰写,以便直接表达要点。

同样的话,用两种不同的语气编写:

  • 有趣:扩大你的社交网络,并随时了解当前流行的事物。
  • 严肃:在最大的社交网络应用程序和在线职位市场上寻找工作。

意外地写出让人感到轻蔑、冒犯和不专业的消息并不罕见。这时语调就发挥了作用。大声朗读你的消息,让他人为你朗读,尝试使用不同的标点符号和句子结构。这就是磨练语调的方法。

另一个思考语调的方法是:你的语气从不改变,但你的语调会变化。你的语气类似于你作为一个人的特点,而语调是你在特定情况下的回应方式。

主动语态和被动语态

一个句子始终包含一个动作者、一个动词和一个目标。它们出现的顺序决定了句子是以主动语态还是被动语态书写。

在主动语态中,动作者排在第一位。例如:“CSS绘制背景。”

使用主动语态的句子比它们的被动语态更加简单明了。它们更加清晰、简洁、易于理解——非常适合用于更专业、更直接表达要点的语气。

而在被动语态中,动作者排在最后。这意味着我们的动作者——在这个例子中是CSS——出现在结尾。就像这样:“背景被CSS绘制”。

读者通常会在心中将被动语态转换为主动语态,这会导致更多的处理时间。如果您曾经听说过使用主动语态更好,那通常就是原因。技术作者大多数情况下更喜欢使用主动语态,只有极少数例外,比如引用研究:“有人建议……”。

但这并不意味着你应该总是追求使用主动语态。如果有效地使用来切换不同的语态——甚至在同一段落中——可以使你的内容从一个句子更顺畅地流向下一个句子。

避免犯错

语法涉及语言的结构和正确性,对于实现这一点,最好的方法就是快速校对你的文档。去除文档中的拼写错误、语法问题和语义缺陷非常重要。

在本文末尾,我会向你展示专业人士用来避免写作错误的无价工具。显然,现在几乎所有东西都内置了拼写检查器;我们的代码编辑器甚至有拼写检查和代码检查插件来帮助我们预防错误。

但是,如果您正在寻找一种集所有语法功能于一身的工具,Grammarly是最广泛使用的工具之一。我没有从中获得任何好处。它只是一个非常棒的工具,许多编辑和作家都用它来写出干净、明确的内容——就像你可能使用Emmet、eslint或任何其他代码检查器来编写干净、明确的代码一样。

编写代码注释

我们为其他开发者写的东西会对我们工作的整体质量产生很大的影响,无论是我们在代码中写了什么,如何解释代码,还是如何对一段代码给出反馈。

有趣的是,每一种编程语言都有一套标准的特性来写注释。他们应该解释代码在做什么。我指的不是像这样模糊的注释:

red *= 1.2 // Multiply `red` by 1.2 and re-assign it

相反,应该使用注释提供更多信息:

red *= 1.2 // Apply a 'reddish' effect to the image

一切都与上下文有关。"我在建立什么样的程序?"这正是你应该问自己的问题。

注释应该增加价值

在我们研究什么是"好的"代码注释之前,这里有两个懒惰注释的例子:

const age = 32 // Initialize `age` to 32
filter: blur(32px); /* Create a blur effect with a 32px radius */

请记住,注释的目的是为了增加代码的价值,而不是重复代码。如果你无法做到这一点,最好将代码保留原样。这些示例之所以“懒惰”,是因为它们仅仅是重述了代码显而易见的操作。在这种情况下,注释是多余的,因为它们在告诉我们已经知道的东西 - 它们并没有增加价值!

注释应该反映当前代码

在大型项目中,过时的注释并不罕见;我敢说在大多数项目中都存在。

让我们想象一下 David,他是一位程序员,同时也是一个非常酷的人。David想要按字母顺序从A到Z对一个字符串列表进行排序,所以他在JavaScript中做了以下显而易见的事情:

cities = sortWords(cities) // sort cities from A to Z

接着,David 意识到 sortWords() 实际上是将列表从 Z 到 A 进行排序。这并不是问题,因为他可以简单地反转输出:

cities = sortWords(cities) // sort cities from A to Z
cities = reverse(cities)

不幸的是,David并没有更新他的代码注释。

现在想象一下,如果我没有告诉你这个故事,你看到的只是上面的代码。你自然会认为在运行了第二行代码之后,cities 列表将从 Z 到 A 排序!整个混乱都是由于一个过时的注释所引起的。

虽然这可能是一个夸张的例子,但如果你在紧急截止日期的压力下赶工,类似的事情可能会发生(而且通常也确实会发生)。幸运的是,这可以通过遵循一个简单的规则来避免:在更改代码的同时更改注释。

这是一条简单的规则,将使你和你的团队免于大量的技术债务。

现在我们知道写得不好的注释是什么样子的,接着让我们看一些好的例子。

注释应该解释不规范的代码

有时,自然的做事方式并不正确。程序员可能不得不"破坏 "一下标准,但当他们这样做时,最好留下一个小评论,解释他们的理由:

function addSetEntry(set, value) {    
  /* Don't return `set.add` because it's not chainable in IE 11. */  
  set.add(value);
  return set;
}

这很有用,不是吗?如果你负责审查这段代码,你可能会想在没有注释的情况下纠正它,说明问题所在。

注释可以明确未来任务

对于注释,另一件有用的事情是承认有更多的工作要做。

// TODO: use a more efficient algorithm
linearSort(ids)

这样,你可以保持对流程的关注。而在以后的某个时间,你(或其他人)可以回来修复它。

注释可以链接到源头

话说,你在 StackOverflow 上找到了解决问题的方法。在复制粘贴该代码后,有时将答案的链接保留下来是一个好习惯,这样你可以在将来参考它。

// Adds handling for legacy browsers
// <https://stackoverflow.com/a/XXXXXXX>

这很重要,因为解决方案可能会变。知道你的代码是从哪里来的总是好的,以防它被破坏。

编写pull request

Pull requests(PRs)是任何项目的基本面。它们是代码审查的核心。如果没有好的描述,代码审查很快就会成为团队性能的瓶颈。

一个好的PR描述总结了正在进行的更改以及为什么进行这些更改。大型项目通常有一个拉取请求模板,就像这个从实际例子中改编而来的模板:

## Proposed changes
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.

## Types of changes
What types of changes does your code introduce to Appium?
 - [ ] Bugfix (non-breaking change which fixes an issue)
 - [ ] New feature (non-breaking change which adds functionality)
 - ...

## Checklist
 - [ ] I have read the CONTRIBUTING doc
 - [ ] I have signed the CLA
 - [ ] Lint and unit tests pass locally with my changes

## Further comments
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc…

避免模糊的PR标题

请避免下面这些标题:

  • Fix build.
  • Fix bug.
  • Add patch.

这些甚至没有尝试描述我们正在处理的构建、错误或补丁是什么。对于构建的哪个部分进行了修复、哪个错误被解决,或者添加了哪个补丁,稍微提供一些额外的细节可以大大促进与同事之间更好的沟通和协作。它可以使人们达成共识并站在同一个起点上。

Pull Request 标题通常使用祈使语态书写。它们是整个 Pull Request 的单行摘要,并应描述 Pull Request 所做的工作。

以下是一些好的示例:

  • Support custom srcset attributes in NgOptimizedImage
  • Default image config to 75% image quality
  • Add explicit selectors for all built-in ControlValueAccessors

避免冗余的PR

一个大的PR意味着一个巨大的描述,没有人愿意审查成百上千行的代码,有时只是为了最终驳回整个代码!

相反,你应该:

  • 与你的团队通过 Issues 进行沟通,
  • 制定计划,
  • 将问题分解成较小的部分,
  • 或者每个部分都有自己的 PR 。

现在是不是干净了许多?

在PR正文中提供细节

与 PR 标题不同,PR 正文是包含所有细节的地方,包括:

  • 为什么要进行这个 PR?
  • 为什么这是最佳方法?
  • 该方法任何不足之处,以及解决方案
  • 相关的 bug 或跟踪单号,基准测试结果等等。

报告bug

Bug 报告是任何项目中最重要的方面之一。所有优秀的项目都建立在用户反馈的基础上。通常来说,在无数次测试之后,仍然是用户发现了大部分 Bug。用户也是伟大的理想主义者,有时他们会提出功能方面的想法,请倾听他们的意见!

对于技术项目,所有这些都是通过报告 issue 来完成的。一个写得好的 issue 可以让另一个开发人员轻松地找到问题并进行回应。

比如,大多数大型项目都有一个模板

<!-- Modified from angular-translate/angular-translate -->
 ### Subject of the issue
 Describe your issue here.

 ### Your environment
 * version of angular-translate
 * version of angular
 * which browser and its version

 ### Steps to reproduce
 Tell us how to reproduce this issue.

 ### Expected behavior
 Tell us what should happen.

 ### Actual behavior
 Tell us what happens instead.

收集截图

请使用系统屏幕截图工具来捕获问题。

如果是 CLI 程序的截图,请确保文本清晰可见。如果是 UI 程序,请确保截图捕捉到正确的元素和状态。

你可能需要捕获一个实际的交互过程来展示问题。如果是这种情况,请尝试使用屏幕录制工具来录制 GIF 动画。

如何重现问题

当 Bug 在程序员的电脑上呈现时,解决起来要容易得多。这就是为什么一个好的提交信息应该附带能够精确重现问题的步骤。

下面是一个例子:

Update: you can actually reproduce this error with objects:

<div *ngFor="let value of objs; let i = index">
   <input [ngModel]="objs[i].v" (ngModelChange)="setObj(i, $event)" />
</div>


export class OneComponent {
   obj = {v: '0'};
   objs = [this.obj, this.obj, this.obj, this.obj];
 
  setObj(i: number, value: string) {
     this.objs[i] = {v: value};
  }
}

 The bug is reproducible as long as the trackBy function returns the same value for any two entries in the array. So weird behavior can occur with any duplicate values.

建议原因

作为捕获 Bug 的人,你可以为为何出现这个 Bug 提供一些潜在的原因。也许 Bug 只在遇到某个特定事件后发生,或者只在移动设备上发生。

探索源码也没有什么坏处,也许可以找出导致问题的原因。然后,你的 issue 会更快地被关闭,而且你有可能被分配到相关的PR。

与客户沟通

你可能是一名独立的自由职业者,或者可能是一个小团队里的主要开发人员。在任何一种情况下,假设你负责与客户在项目上进行沟通。

现如今,程序员的刻板印象是我们不擅长沟通。我们以过于技术化的术语表达自己,告诉别人什么是可能的,什么是不可能的,甚至当有人质疑我们的方法时,我们会变得有防御性。

那么,如何缓解这种刻板印象?询问客户想要什么,并始终听取他们的反馈。以下是如何做到这一点的方法。

询问正确的问题

首先要确保你和客户的想法是一致的:

  • 您的目标受众是谁?
  • 网站的目标是什么?
  • 您最近的竞争对手是谁,他们做对了什么?

提问也是以积极的方式写作的好方法,特别是不同意客户的反馈或决策的情况下。提问迫使对方支持自己的主张,而不是通过为自己的立场辩护来攻击他们:

  • 您对此是否满意,即使它带来额外的性能成本?
  • 移动组件是否有助于更好地实现我们的目标?
  • 太好了,谁负责在启动后维护它?
  • 您知道这两种颜色之间的对比是否符合 WCAG AA 标准吗?

推销自己

如果你要向潜在的客户进行推销,你就需要说服他们雇用你。客户为什么应该选择你?提出以下内容很重要:

  • 你是谁
  • 你在做什么
  • 为什么你很适合这份工作?
  • 你所做过的相关工作的链接

一旦你得到了工作并需要起草合同,请记住没有比一堆法律术语更令人生畏的内容了。即使它是为设计项目编写的,Contract Killer可以成为编写更加友好的合同的不错起点。

你对细节的关注可能是你和其他开发者赢取同一项目的区别。根据我的经验,客户容易雇用他们认为会喜欢与之合作的开发者,而不是技术上最有能力或经验最丰富的开发者。

编写微文案

微文案是编写用户友好的UI信息的一门艺术,例如错误消息。我敢打赌,作为开发人员,你有时不得不编写错误消息,因为它们一直被搁置到发布时间。

这可能就是为什么我们有时会看到这样的错误:

Error: Unexpected input (Code 693)

错误是你最不希望用户遇到的问题。但它们确实会发生,我们无能为力。以下是一些提高微文案技能的技巧。

避免技术术语

大多数人不知道什么是服务器,而程序员100%知道。这就是为什么在错误消息中会看到像 API 或超时执行这样的不常见术语。

除非你面对的是技术客户或用户群体,否则你的大部分用户可能没有上过计算机科学课程,不知道互联网是如何工作的,也不知道为什么某个特定的东西不起作用。

因此,一个好的错误消息不应该解释为什么出现问题,因为这样的解释可能需要使用令人生畏的技术术语。这就是为什么避免使用技术术语非常重要。

不要责怪用户

想象一下:我正在尝试登录你的平台。我打开浏览器,访问你的网站,输入我的详细信息。然后我被告知:“您的电子邮件/密码不正确。”

尽管认为这个信息是敌对的似乎很夸张,但它在潜意识里让我觉得自己很愚蠢。微文案表示,千万不要责怪用户。尝试将你的消息更改为指责性更少的内容,例如:“抱歉,该电子邮件密码组合不正确。我们可以帮助您恢复帐户。”

我还想补充一点,避免使用全大写字母和感叹号非常重要!当然,它们可以用来传达兴奋的情绪,但在微文案中使用会给用户带来一种敌对感。

不要让用户不知所措

在微文案中使用幽默是个好主意!它可以缓解情绪,是减少负面影响的简单方法。

但是,如果你使用不当,幽默也有可能会让用户感到轻蔑和侮辱。这是一个巨大的风险。

不要不顾一切地去开玩笑 - 强行幽默可能比不幽默更糟糕。如果你不确定,请保持正直的表情。

编写无障碍标记

我们可以轻松地撰写一篇关于无障碍性,以及与技术写作相关的文章。事实上,无障碍性通常包含在内容样式指南中,包括微软Mailchimp的指南。

作为开发者,你可能已经非常了解无障碍性。你甚至可能是很勤奋的开发者之一,将无障碍性作为工作流程的核心部分。但是,无论我们觉得无障碍性是多么重要,无障碍性仍然是低优先级。

因此,如果你发现自己正在将他人的文案编写到代码中,为其他开发者编写文档,甚至自己编写UI文案,要注意一些基本的无障碍最佳实践,因为它们完善了所有其他技术写作的建议。

一些需要注意的事项包括:

  • 尽可能使用语义标签(例如 <nav>、<header>、<article> 等)
  • 遵循逻辑的标题结构
  • 为图片添加 alt 文本
  • 注意行内语义

总结

这些是展示技术写作和开发相互关联的六种方式。虽然这些例子和建议可能不是什么高深的技术,但我希望你能够发现它们有用,无论是与其他开发人员合作、维护自己的工作、在紧急情况下编写自己的副本,或者起草项目提案等等。

最重要的是:磨练你的写作技巧,在写作上多花点功夫,可以使你成为一个更好的开发者。

以上就是本文的全部内容,如果对你有所帮助,欢迎收藏、点赞、转发~