最近,一边在思考如何进行开发者体验优化,一边在设计新的文档体系,以确保文档和代码的一致性。于是,便结合我先前对于文档代码化的理解和实践,并展开对于 Rust、Julia、Dart、Kotlin、Swift 等语言的文档研究(详细见:《API 库的文档体系支持:主流编程语言的文档设计》),重新思考了如何做了文档工程的开发者体验设计。
本文的面向编写文档的工程师,关注于他们如何能提高自身的开发体验。
我尝试性的去梳理过去在编写文档的一些痛点,诸如于:
还有一些问题,可能是难以通过自动化的方式来解决的,诸如于:
于是,我们可以尝试性地借用业内一些通用的方式来解决问题。
再回到标题上,让我对标题做一些解释:
文档工程用于帮助我们指定、设计、和实施计算机技术相关的文档,如产品特定规格或详细说明,以及创建和使用它们的流程。它的特点是以“文档为中心”,以帮助我们构思和理解如何支撑其所在的商业模式。
而文档工程体验设计,则是围绕于构建和设计文档的过程进行的体验改善。即目标用户是编写文档的工程师,改善其编写文档的体验。并针对于文档的目标用户,改善他们在文档方面的体验(PS:这部分不是本文讨论的重点)。
文档体验是开发者体验的一个关键性因素,用于指导新手快速上手技术产品。在我们设计各类开发者体验指标时,一个非常重要的指标就是 TTFHW(Time to first hello world),即从零到第一个 Hello World 需要的时间,而这个指标是严重依赖于开发者文档。
因此,本文的意图是从文档开发者的体验出发,以重新塑造整体的开发者体验。
既然文档工程体验归属于开发者体验,它面向的是开发者提供更好体验,对于自身而言,更需要非凡的体验。只有以此为出发点,才能减小文档团队人员的流 动,毕竟不是程序员想写文档,也不是程序员都想看文档的。
作为一个程序员,我设计和参与过两个文档系统(Ledge 便是其中之一),它们之间有各自不同的思想。再结合我对于多个语言的文档体系的分析和设计,我觉得一个优秀的文档工程应该是满足这样的条件:
除了上述的要素之后,我们还需要提及一个非常重要的因素,即针对于不同的场景,应该要有不同的文档呈现形式。诸如于:
尽管文档很重要,但是请不要忘了,我们的初衷是带来更好的用户体验。
为了更方便于讨论,我尝试性对所接触的文章进行了模式上的分类,以及它们所适用的场景:
在文档工程这个上下文下,其详细的定义如下。
定义:文档代码化是将文档以类代码的领域特定语言的方式编写,并借鉴软件开发的方式(如源码管理、部署)进行管理。 它可以借助于特定的工具进行编辑、预览、查看,又或者是通过专属的系统部署到服务器上。
示例:各类的开源软件文档、Rust、Julia 等编程语言的文档系统
文档代码化其中是现代化的文档工程里的基石。现有的开源软件文档体系,都是以 markdown + 开源的形式而展开的,所有的人都可以在这之上进行协作。除此,基于不同文档的需求,它们会在 DSL 的基础上进行扩展,如新一代的编程语言的文档系统。它们的方式是这样的:
更详细可以参考:《API 库的文档体系支持:主流编程语言的文档设计》
定义:文档测试的原始定义是,一种测试方式,用于确保系统的文档与系统的功能相匹配。在文档工程的上下文里, 我们定义为针对于文档中的代码验证其有效性,以及其结果的准确性。
示例:Rustdoc、DocumenterTools.jl
如在 Rustdoc 中代码中的注释中的代码会被提取出来,它会被独立编译,确保代码是可运行的。
# Examples
```rust
assert_eq!(2 + 2, 4);
```
如下是 Rustdoc 中将上述的代码生成测试代码的测试用例:
#![allow(unused)]
fn main() {
#[allow(non_snake_case)]
fn _doctest_main__some_unique_name() {
assert_eq!(2 + 2, 4);
}
_doctest_main__some_unique_name()
}
一旦上述的代码编译并运行通过,则说明文档中的注释是正确的。具体的步骤如下:
详细见 Rustdoc 相关源码:librustdoc
定义:可执行文档是指文档本身已经是代码化的结果,它像代码一样可以执行, 并且可以将结果动态地与文档结合在一起。
示例:Julia 的 DocumenterTools、R Markdown、Exemd
在 R Markdown 里,它可以结合文档与 R 语言源码,可以进行动态的渲染。我们可以在 markdown 文件中,“随意”地调用 R 中的函数,并动态地嵌入数据、代码、计算结果、可视化图表等到输出的文档中。在结合了 Pandoc 之后,文档可以输出到所有主流的文档格式。如下的示例:
```
{r fig.show='animate', dev='jpeg', ffmpeg.format='gif'}
for (i in 1:10) plot(runif(100), ylim = c(0, 1)) # for example
```
它将会运行并在文档中嵌入运行的结果。
定义:灵活代码块是指文档可以通过 DSL 动态引用源码中的内容。
示例:DocumenterTools.jl、Forming 里的 Writing
以我设计的 Writing 为例,它可以动态解析 markdown 中设计的 Writing DSL,并从代码中读取对应的代码块。如下是 Writing 的示例:
// doc-code: file("src/lib.rs").line()[2, 5]
// 读取 "src/lib.rs" 文件的第 2 到第 5 行
// doc-section: file("src/lib.rs").section("section1")
// 读取 "src/lib.rs" 文件中的 section1 相关的代码块
通过简单的自定义函数,将文档与代码有机结合到一起。只要应用编译运行成功,那么文档本身也是正确的。
定义:测试即文档即指测试用例以文档的形式编写,文档本身就是测试用例。
示例:Cucumber
相信大家都很“熟悉”了,主要是在自动化测试中使用非常广泛。Cucumber 示例如下:
# language: zh-CN
@math
功能: 加法
加法计算器的验证用例
@sanity
场景: 两个数相加
假如我已经在计算器里输入6
而且我已经在计算器里输入7
当我按"相加"按钮
那么我应该在屏幕上看到的结果是13
测试是文档,文档即是测试。
文档同构。文档同构 是一种将代码与文档保持一致的技术理念,它能读取格式化的文档,并将文档自动加入到代码中,如以注释的形式或者是只在 IDE 呈现;同时,还能将读取代码中的文档,自动更新到文档中,或是对文档进行测试和差异对比。
PS:我正在设计的一种方式,暂时没有 DEMO。
最后,进行最后一个不愉快地话题,讨论一下如何优化这方面的指标。实际上,我并没有任何相关的经验。只是呢,我试想了一下,开发者体验相关的体系,修改一下,理论上也可以在这里适用。
文档的度量本质上还可以使用开发者相关的指标进行度量,诸如于:
从 API 相关的用户体验来说,它还可以是:
还有一些不是那么易于衡量的:
不过呢,线上的文档作为一个网站 ,常规的 Web 应用的指标也是适用的:文档访问速度等。
为了这个文档的概念完整性,我复制/粘贴了一些我司关于开发者体验优化相关的步骤:
从模式上来说,它和用户体验是极为相似的,同样的也是出于指标度量的维度来考虑问题的。
网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
添加我为好友,拉您入交流群!
请使用微信扫一扫!