专业的编程技术博客社区

网站首页 > 博客文章 正文

写代码的这群人不写文档,为什么 (上篇)

baijin 2024-09-06 14:52:40 博客文章 6 ℃ 0 评论

笔者今天想谈论程序员群体中一个比较普遍的现象,或许是外部不太容易关注及发现到的现象,就是:我们这个群体中很多人不愿意写文档。

就这个点,我甚至又去翻阅了《程序员的职业素养》这本书,因为我印象中好像这本书没有讲到文档这个点,查证了下果然没有讲到这个点。

笔者心中疑惑不解,是因为相比国内的环境,国外的程序员不存在这个现象,还是Rober C. Martin觉得这个点不重要?

当然,笔者要坦承自己的观点:作为程序员,必要的文档的编写,是自身职业专业性不可缺少的一个方面。

一)

首先,笔者先解释自己对文档范围的定义。对于程序员来说需要编写的文档包括哪些范围?

笔者认为以下的一些范围都属于该程序员负责的文档:

  • 代码注释,注释本身就是文档的一种
  • 团队技术规范文档,用来指引及约束团队编码的一致性
  • Api文档
  • 核心领域模型
  • 系统架构说明类文档

上述几点是笔者认为作为一个程序员,你在职业生涯中或早或迟会遇上需要你来做的事情。

但事实上,笔者感觉上述文档普遍存在缺失。

那原因是什么?

二)

笔者分析了几个原因,或许或多或少能覆盖一些这种现象的原因吧。

  • IT行业中普遍存在以结果为导向
  • 编写文档易,维护文档则难
  • 为什么要写文档:代码就是最好的注释
  • 敏捷软件的流行及其宣言之一:可以工作的软件胜过面面俱到的文档
  • 我们写不出专业的文档,所以不想写

接下来,笔者逐一分析下这些点。


以结果为导向

在我们这个行业,由于竞争激烈,叠加管理复杂,所以慢慢的形成了一种以结果为导向的管理风格,普遍对过程并不在意,因为关注过程比关注结果需要耗费更多的时间与成本。

那理所当然的,对于编写文档这个过程中需要关注的事情,管理者普通也并不在意,而我们程序员这个群体,普遍也存在除了写代码以外其它事不要找我类似的心态,也会慢慢的自己都不太关注文档这个事情。甚至一些情况下,因编写文档所花费的时间可能还会被管理人员诟病。

上述情况都加剧了程序员不写文档这个趋势。

事实上,笔者在过去几年,自己编写的一些文档均出自认为需要,没有任何管理者要求笔者做过这个事情。可见在管理层面上,这个事就是被忽略的一个事情。

由于结果比过程更重要,管事的都不关心,又如何能期望程序员自觉呢?


维护文档是需要时间及成本的

事实上,无论上述笔者所说的几种文档中的任何一种,都普遍存在一个问题:

维护文档太累

文档这个东西,它和代码几乎是一样的,不是一个一次性的活。不是说我写了一个架构文档,就可以交差了,你的代码时时在修改,同时可能意味着你的文档需要同步时时去更新。

这个事情太麻烦了,而且普遍不容易做到,于是很容易形成过时文档。麻烦到以至于代码简洁之道中对于注释这个点,干脆建议

代码就是最好的文档,文档非常容易过时

所以,对于程序员来说,要持续地更新维护这些文档,是个很累人的活,而且依靠程序员的自觉性。

但凡依赖个人自觉性的东西,普遍都不能期望太高。


代码就是最好的注释

很多程序员都熟悉这句话,这句话成为了他们不写文档的『说词』,笔者在前面解释过了,由于注释易于过时,于是干脆建议不要写注释,简洁优雅的代码才是最好的注释。

但很多程序员对这个的理解出现了一些偏差,表现在:

偏差一:没有意识到这个仅适合于注释,但文档的范围远大于注释

代码写的再好,也只能是用于解释说明一段细节的代码是如何运行或表意的。再优雅的代码,你也只能通过它的命名,参数来理解这段代码是用来做什么的。

这是非常微观的层面的事宜。但项目或产品,还有更宏观的事宜,比如你的整体设计规范,技术选择及其在架构中的作用,还有公开给其它服务调用的API等,类似的东西与注释压根不处于同一个层面。

你能和一个新来的团队成员在解释项目架构时,让他去看代码么

偏差二:没有理解只有好的代码才是最好的注释,而不是代码

代码和好的代码并不是一回事。

直白点说,大多数程序员不具备这个能力,其代码压根不能作为注释。理解这些人的代码,还不如期望他们写点注释来得更简单直接。

偏差三:不写单元测试

虽然代码简洁之道中说过了代码才是最好的注释,但事实上并不是,如果你熟知TDD并且编写单元测试,你就会明白,单元测试才是最好的注释。

单元测试虽然也是代码,但由于程序员大多数编写的实现功能的代码并不是一个事情,况且事实上,大多数程序员并不编写单元测试。

本代码摘自myddd-vertx,基于Kotlin与Vert.x的响应式领域驱动实现

class GuiceInstanceProviderTest {

  companion object {
    private var injector:Injector? = null

    @BeforeAll
    @JvmStatic
    fun beforeAll(){

      injector = Guice.createInjector(object : AbstractModule(){
        override fun configure() {
          bind(InterfaceA::class.java).to(ObjectA::class.java)
          bind(InterfaceB::class.java).to(ObjectB::class.java)
          bind(InterfaceA::class.java).annotatedWith(Names.named("AnotherA")).to(ObjectA::class.java)
        }
      })
      InstanceFactory.setInstanceProvider(GuiceInstanceProvider(injector))
    }

  }


  @Test
  fun testGetInstance(){
    val objectA = InstanceFactory.getInstance(ObjectA::class.java)
    Assertions.assertNotNull(objectA)
    Assertions.assertNotNull(objectA.getB())
  }

  @Test
  fun testGetInstanceByName(){
    val objectA = InstanceFactory.getInstance(InterfaceA::class.java)
    val anotherA = InstanceFactory.getInstance(InterfaceA::class.java,"AnotherA")

    Assertions.assertNotNull(anotherA)
    Assertions.assertNotEquals(objectA,anotherA)
  }
}

如笔者的一个Guice的IOC实现,能有比上述单元测试更好说明如使用这个代码的文档么?

因此:单元测试才是最好的注释

除非你有编写单元测试的习惯,又认为自己的代码足够简洁与优雅,否则笔者认为代码才是最好的注释并不适合你,还不如老老实实写点注释,帮助别人理解你的代码。


可以工作的软件胜过面面俱到的文档

2001年2月,17位软件专家在雪鸟镇聚会,讨论软件开发的糟糕现状。在这之前流行的是瀑布方法,最终,这群人讨论出了一个新的模式,就是敏捷软件开发。

在国内,很多团队也认为自己是基于敏捷软件理念来管理团队进行项目开发,其中敏捷软件的四个宣言中,有一个非常重要的点就是:

可以工作的软件胜过面面俱到的文档

于是一些程序员借由这个,干脆把文档给忽略掉了。直接以可以工作的软件来说明一切。

我认为这是对敏捷软件宣言的一个误解,我们需要理清敏捷软件理念提出的背景,背景就是大家发现过往的瀑布开发很难适应需求多变的软件开发。

瀑布开发严格主张先设计,后编码,把设计做到面面俱到。事实上,这种模式是过往在其它行业被证明是可行的方式,比如建筑行业。

但它压根不能适应需求多变的软件开发。

敏捷软件提出这个宣言的本质,也是为了避免面面俱到的文档,基于软件需求多变的现状,按照瀑布开发理念的面面俱到,事无俱细的文档是不切实际而且浪费时间的。

但不意味着开发过程中,完全不需要文档。


反例

这一点,笔者虽然没有亲身体验,但想必很多人和笔者一样听说日本软件行业其实就是严格的瀑布软件开发理念,在开发前,文档面面俱到,开发过程中不能有丝毫违反文档的地方。

虽然日本人这种精细的精神值得学习,但他们在软件行业这个搞法,我估摸着也是他们做不出优秀软件的原因所在吧。软件开发怎么可能事先计划好?


我们写不出专业的文档

虽然笔者把这个排在最后,但笔者认为可能这才是最重要的一条。事实上,以笔者所见,我们之中很多程序员压根写不出专业的文档。

我们很多程序员在写文档前最先问的就是:有没有模板或格式?因为如果没有,都不知道怎么写出一份设计或架构文档,甚至不知道该写什么。

不管有没有模板或规定的格式,事实上,我见过很多程序员写的文档,阅读起来不太通顺,思维不清晰,很难称得上一个专业的文档。

比如行业内常见的UML图,可能大多数程序员都没有认真学习或使用过。

再比如,在描述一个系统架构时,行业中比较著名的一个规范是: *"4+1"视图模型*

Kruchten 提出了一个"4+1"视图模型

从 5 个不同的视角包括包括逻辑视图、进程视图、物理视图、开发视图、场景视图来描述软件体系结构。每一个视图只关心系统的一个侧面

5 个视图结合在一起才能反映系统的软件体系结构的全部内容。


我认为大多数程序员,可能就算是架构师,可能不太清楚这个,也有知道可能很少有按照这个要求来写文档的。笔者也是从一位朋友那听说的才知道这个。


文档如代码

笔者认为:写文档这个事应该如同写代码工作是一样的,只是用不同的形式来描绘自己的想法与思维。

所以,一个优秀的程序员,理当能写出好的文档,这应该是一脉相承的。

笔者相信:作为程序员,必要的文档的编写,是自身职业专业性不可缺少的一个方面。



下篇笔者结合自己的经历,分享下自己工作中是如何编写文档的,期望给各位一个参考。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表