跳转至

结束语 写代码是一件可以一生精进的事

你好,我是郑晔。

春节将至,祝你新春快乐!我们的专栏到这里也正好要更新完结了,在结束语这一讲,我想和你聊聊程序员精进的话题。

创作《10x 程序员工作法》之初,我曾经定下了“写下 100 篇”的宏伟目标。在第三个专栏结束的时候,这个当年许下的宏伟目标终于实现了。

如果为这 100 篇的内容找一个共同的主题,那就是程序员精进之路。

程序员精进之路

在很多人心目中,程序员是一个辛苦的职业,一方面,各种新东西层出不穷,程序员们要努力追随,另一方面,业务飞速发展,我们唯有积极应对。那么,是什么支撑你在这个富有挑战的行业里坚持前行呢?

于我而言,这个问题的答案是,热爱。

在我的心目中,编程是一项有趣的智力活动,从最初解决一个特定的小问题,到现在创造一个方案去解决一个系统的问题,无不需要费尽心力去探寻一个好的解决方案。时至今日,即便我写程序已经二十多年了,但每次程序运行通过时,我心里依然还是有一些小激动,因为支撑程序运行的每行代码里都有自己的思考在里面。

正是每次一点点积累起来的成就感,激励着我不断去探索更好的做法。一开始,为了解决特定的问题,我四处搜集着各种编程技巧。当我理解了基本功的重要性后,就去拼命地补齐各种基础知识,构建起一个知识体系。随着开源软件运动的兴起,我知道了,原来有各种工具和程序库可以简化自己的工作。因为见识过别人的运指如飞,我曾专门练习了各种快捷键和命令行。

当我已经能够很好地解决自己面对的各种功能问题时,我开始抬起头,有了更大的视野。

我学习了各种软件设计的知识,让自己的代码不仅仅是为了今天,也能够面对未来。我学习了各种程序设计语言,看到了隐藏在语言背后的编程范式和思考习惯。我学习了各种软件开发的最佳实践,懂得了怎样让一群人更好地协同。

我做的所有努力,都是为了更好地写代码。

有了对于软件开发更多的思考,回过头再来写代码时,我就能看到更多的维度,能意识到自己在写的代码对他人和未来的影响,这时自然会尽力把自己的代码写得更整洁。

时至今日,如果你问我,对自己写的代码满意吗?我的答案还是不满意。写代码是一门手艺,需要不断地打磨。一方面,坚持写代码,保持自己对于代码的体感;另一方面,保持对于代码的敏感度,不断思考对于代码的改进,寻找更好的写法。

经过一段时间,我总会发现代码中让我不满意的地方,这会成为新的驱动力,让我进一步扩充自己的知识,把新的理解注入到代码之中。每次拓展知识边界,与之相伴的都是极大的智力愉悦。也正是这种智力上的快感,让我得到了进一步前进的动力。一个正向反馈的循环就是这样逐步推进,让我在写了二十多年代码之后,依然乐此不疲。

我在《软件设计之美》中讲过,一个好的设计是在一个“小内核”上构建起来,然后,逐步添加更多模型。我们的知识拓展过程也是如此。我的“小内核”就是编写代码这件事,所有一切知识的拓展都是围绕这个内核展开的。

写代码是一件可以持续一生的事情,但前提条件是,找到自己的热爱,建立起自己的正向反馈。坚持写代码,发掘代码中值得改进的地方,不断拓展自己的知识边界,寻找更好的代码写法,这就是最朴素的程序员精进之路。

代码的敏感度

对于一个不断精进的程序员而言,发掘代码中值得改进的地方,需要对代码有细致入微的敏感度,这样才能体察代码间细微的差别。

我给你举个例子:注释。

代码该不该写注释呢?在一些人看来,没有注释的代码不值得写,这甚至成了一些程序员的宗教信仰。如果你问他们为什么要写注释,他们的回答多半是“让程序更加容易理解”。

但有另外一群人则将注释视为坏味道,他们会说,为什么不把代码写得更清楚,让代码不需要注释呢?被逼到角落的“注释程序员”依然不会束手就擒,他们不会承认自己不能把代码写清楚,而会说,有些代码必须要有注释才能解释清楚,比如一些算法。

好了,双方的主要观点陈述完毕。你怎么看待注释呢?

早在 1984 年,《计算机程序设计艺术》的作者 Donald Knuth 就给出了一个回答,他提出了“文学编程(Literate Programming)”的概念,其核心要义就是要将程序写得像用自然语言进行表达一样顺畅。虽然作为一种编程范式,它并没有流行起来,但它背后蕴含的思想却影响了很多人,也给我们提出了更高的技术追求。

一个好的程序应该像一篇优美的文章,读起来自然流畅,二者背后有诸多相通之处,你会看到,许多优秀程序员都有着优秀的表达能力。所以,回到写代码本身,把程序本身写得更清楚直白才应该是我们的追求。关于如何把代码写好,我在这个专栏已经讲了很多了。

具体“注释”这件事上,我的观点是,“注释”有其价值,但不应该是主力。我们没见过哪篇文章是要求把注脚作为主旨的,同样,过于强调注释,无异于本末倒置。写代码首先应该是把代码本身写好,至于那些确实无法用代码陈述清楚的部分,我们再考虑用注释。

所以,我赞同把“注释”当做坏味道的提示,先竭力把代码写到不需要用注释,而把注释当作最后的选择。确实有一些特定的处理需要注释,无论是一个精巧的算法,还是一个特殊的技巧。用这个标准要求自己,你会发现,大多数代码其实不需要注释,因为它们太普通了。

你看到了,即便像注释这么简单的东西,写与不写,背后都有着可以探究的各种细节。诚如我在前面所说,写代码是一门手艺,需要不断地打磨。唯有不限界地拓展自我,才可能对代码有细致入微地把握。

你发现了,打磨手艺,锤炼自己对于代码的敏感度,坏味道是一个不错的出发点。这也是我写这个专栏的初衷,帮你从识别出那些你曾视而不见的“坏味道”,提升你对代码的敏感度。

在这个专栏中,我给出的就是全部的坏味道吗?显然不是。只要拿出《重构》对照一下,你就会发现,坏味道还有许多,比如,霰弹式修改和发散式变化。我没有拿出来讲,不是它们不重要,而是它们不像我在这个专栏中罗列的这些坏味道那样,有非常直观的表现。

比如,霰弹式修改说的是一次变化要在很多类的内部做修改,但能否察觉出自己改了很多类,这就依赖于每个人的敏感度了。

同样,发散式变化说的是,不同的变化都会改到同样的模块上。发现这种坏味道,需要你意识到,对同一个模块的修改是由于不同的原因造成的,这对于敏感度的要求就更高了。

无论如何,“知道”有哪些坏味道是第一步的。我建议你在学习了本专栏之后,花上一点时间,通读一下《重构》的第三章“代码的坏味道”,在开篇词中我就提到过这件事,但与那时不同的是,现在你已经通关了我们这个专栏。

我在专栏里讲的所有这一切,一方面,让你对一些代码的坏味道有直观的认识;另一方面,也是更重要的,对于这些坏味道的分析,是为了帮你看到代码里的细微之处,帮助你提升对于代码的敏感度。有了不同的敏感度,再去通读“代码的坏味道”,你会有不一样的收获。

这些道理都是知易行难,今天我们的课程就告一段落了,但是你的精进之路并未停止。

有了“坏味道”的基础之后,接下来最重要的是,你要在实际的工作中反复地锤炼自己的编程手艺,用这些坏味道作为尺子,衡量自己的代码,不断地找到代码更好的写法。这个专栏以及它的两个“兄弟”,帮你开启了程序员的精进之路,但这条路,总归还是要自己去走!

这次的《代码之丑》的旅程就暂告一段落吧,如果以后有机会,我会再来与你分享我对软件开发的理解。

专栏结束了,你也可以在留言区提问,我看到还是会回复的。也欢迎你点击下面图片,为我的《代码之丑》评分、提建议。期待你的反馈,再见!

精选留言(15)
  • qinsi 👍(25) 💬(2)

    个人感想: * 郑老师从业二十多年依旧在打磨编程手艺,瑞思拜! * 依稀记得RUP刚出来的时候,就有人认为今后程序员会被淘汰,因为你甚至可以画画图就生成代码。二十多年过去了,为什么编程仍旧是一门手艺活,而不是大规模的工业化生产? * 我觉得大厂们应该早就实现了工业化生产,毕竟好多年前就可以在一天之内复制粘贴出一个竞品App出来。那么在这样的大厂的工业化生产中,个人手艺的重要程度有多少呢? * 说到磨练手艺似乎就会讲到匠人精神,讲到匠人精神大多会拿日本举例子。举个听来的日本刀的例子。职业的刀匠花费大量时间人工打磨的日本刀可以作为工艺品卖出高价,但如果要大规模装备军队的话,就只能依靠工业化生产降低成本。日本刀的收藏家会为刀匠的手艺买单,那么是否会有客户为编程的手艺买单呢? * 通过文学编程来反对注释可能有些牵强,毕竟曾经有段时间通过在代码注释里写文档再把文档抽取出来(如JavaDoc)也被称为文学编程。程序员不爱写注释和不爱写文档的理由应该是一样的,那么解决的方法只有两种:要么代码像文档一样清晰,要么文档本身就是可执行的代码。郑老师讲的应该是前者,而个人理解的文学编程是后者。文学编程在数据科学/机器学习等研究性质的编程中用得较多(如Jupyter Notebook)。生产系统中要用的话,可能会是DSL的形式?(如Cucumber) * 散弹式修改和发散式变化,应该能够通过自动化分析提交历史得出,这样就不需要依赖个人判断了。不知道都有哪些工具实现了?

    2021-02-09

  • webmin 👍(6) 💬(1)

    关于注释最近我也冒出了困惑,事由是这样的新来了一位同事他写注释很勤奋,几乎达到一行代码一行注释,当时隐隐觉得不对劲,Review他的代码后,发现基上是业务怎么要求他就怎么翻译为代码,缺少聚合和封装,因为大家不是一个项目组,且我也不负责考核他,所以就没有去做进一步的事。 故事到这你肯定好奇我为什么会去关心他的代码和注释,这是因为这哥们做我背后,他打字手很重,就像一挺JQ在持续扫射,以我的经验除了聊天时大家打字有那么快以外,非除是遇到代码大神已经 把绝大部分的事想得很清楚一气合成所有的代码,要不都会在编码时有停下来一段思考的时间,在一天中不会连续高强度的持续输出有效代码。今天在看到"一个好的程序应该像一篇优美的文章,读起来自然流畅,二者背后有诸多相通之处,你会看到,许多优秀程序员都有着优秀的表达能力。"深以为然,作家在写作时是要经过反复构思来回修改的,形象点的说法叫磨稿。

    2021-02-09

  • 穿越时间与空间的旅行家 👍(6) 💬(1)

    感谢老师的分享,由于最近项目重构,学了老师的课感觉受益非浅。中间又去听了10x程序员和软件设计之美。希望能早日看到老师的新课程。

    2021-02-09

  • ifelse 👍(3) 💬(2)

    感谢郑老师,我把您成称作真正第一位教我怎么写代码的老师。自己以前写代码觉得别扭的地方,原来就是缺乏设计,体现了坏味道。看了老师的3篇专栏,让我茅塞顿开。还有老师的一篇 "程序员的测试课"" 专栏,我已经迫不及待要去学习了。

    2022-06-03

  • 捞鱼的搬砖奇 👍(3) 💬(1)

    当年听你的10x 的做了个一份xmind https://gitee.com/meiyoudaima/xmind/tree/master/10X 现在这门课收尾了,准备整理下,再做一次记录 谢谢老师,期待下一门课程。 祝老师新年快乐。

    2021-02-11

  • Jxin 👍(3) 💬(1)

    1.结束得太快了。100章结束了,下一站做啥?期待下个专栏。 2.感谢郑老师的分享,我们下次再见。

    2021-02-09

  • 小钟 👍(2) 💬(1)

    谢谢老师,从老师的文字可以看出老师对写代码的诚意。老师的三门课程都买了,有两门看完了。虽然课程名字和主题不算高大上,但是内容真的觉得很实用。希望老师可以继续写更多的专栏!

    2021-03-27

  • sun 👍(1) 💬(1)

    老师,想请教一个问题,java8提供的函数接口中有了Supplier<T>,为什么还要再提供IntSupplier,DoubleSupplier...呢

    2021-07-16

  • 续费专用 👍(1) 💬(1)

    纸上得来终觉浅,觉知此事要躬行,老师的文章很有实际价值,我这段时间收获很多,希望后来的人也能读到这个专栏,动手实操,也能和我一样有很大的收获。

    2021-02-20

  • 阿尔法 👍(1) 💬(1)

    郑老师,问个问题,我看一些好的开源软件各种继承、实现类关系很复杂,这些开源软件开发之前是需要建模吗?这么多关系怎么分配?

    2021-02-19

  • Edison Zhou 👍(1) 💬(1)

    正在再次复习重构的第三章,呼呼。

    2021-02-09

  • 布凡 👍(1) 💬(1)

    上班最后一天,学完了老师的代码之丑,也愿自己在写代码的路上越来越精进,不断超越自己,也祝老师和同学们春节快乐(*^_^*)

    2021-02-09

  • 6点无痛早起学习的和尚 👍(0) 💬(1)

    2023年11月24日08:54:41 再次留言,把郑大的 4 门课都结合起来一起看,并且在工作中实践了代码之丑的坏味道,超级超级有成就感,让我感觉每天做着乏味枯燥的 crud 工作焕发了新的生机,让我热爱起来了写代码这个事,非常想加郑大微信给郑大表达一下感谢,天天早上就在郑大的各个文章里留言

    2023-11-24

  • 温雅小公子 👍(0) 💬(1)

    应用了老师的小方法后,今天在课堂上给同学做分享,他们说我写的代码真好看。

    2022-09-27

  • Geek_01c5f4 👍(0) 💬(1)

    不由自主,把每个郑老师的专栏都买了,隔一段时间,重新看一看,领悟一下,重温一下,在项目中用一下

    2022-01-22