把错误关在笼子里
人人都会犯错误,还重复犯,还不能批评,这怎么能编写出优秀的代码呢?换句话说就是,我们怎么样才会少犯错误呢?
- 提高程序员的修养,是一个永不过时的课题。从别人的失败和自己的失败中学习、积累、提高,是一个程序员成长的必修课。
- 编译器在代码质量方面,作为机器,恪尽职守,它可以帮助我们清除很多错误。
- 软件测试尽可能地覆盖关键逻辑和负面清单,以确保关键功能能够正确执行,关键错误能够有效处理。
- 代码评审是一个有效的在软件研发过程中抵御人类缺陷的制度。通过更多的眼睛检查软件代码,被忽视的错误更容易被逮住,更好的设计和实现更容易浮现出来。
- 静态代码分析(Static Code Analysis)是通过对源代码的检查来发现潜在问题的一种软件质量保障方式。有很多静态代码分析工具可以帮助你检查代码缺陷,比如说商业软件 Coverity,以及开源软件 FindBugs。
程序员优秀的特质
- 掌握一门编程语言。优秀的程序员需要写的一手好代码,再简单来说,最起码需要能够熟练操控一门编程语言。编程语言,基本上是相通的。掌握了第一门编程语言后,第二门语言学起来就快很多,第三门语言学起来更快。现在我们几乎都是多语言使用者,但一定要先精通一门语言,达到像用筷子那样的熟练程度。
- 解决现实的问题。要解决具体的问题,仅仅做到熟练使用编程语言是远远不够的,我们还需要更多工具。如果做前端,需要理解 HTML 和浏览器;如果做后端,需要掌握数据库和操作系统;如果做云计算,需要掌握 Kubernetes 等等。
- 发现关键的问题。能够发现关键的问题,意味着我们可以从一个被动的做事情的程序员,升级为一个主动找事情的程序员。能够发现关键的问题,往往需要我们对一个领域有很深入的研究和深厚的积累,并且对新鲜事物保持充分的好奇心和求知欲。
- 沉静的前行者。我们写的每一行代码,都可能存在问题。有时候,我发现别人的代码的问题;有时候,别人发现我的代码的问题。我们最后都会明白,要坦诚地面对别人的问题,也要坦然地面对自己的问题。在解决问题和帮助别人解决问题中,我们把一个产品变得越来越好,问题越来越少。
- 时间管理者。要做只有你才能做的事情。是的,有很多事情,只有你可以做,只有你做得最快最好。其他的同事也是一样的,有很多事情,只有他们能做,只有他们做得最快最好。选择最合适的人做最合适的事,这不仅是领导的工作分配,也可以是我们自己的协商选择。
避免过度设计
软件是为现实服务的,而现实总是变化的。作为程序员,我们是没有办法抵制住所有的需求变更的。为了限制无节制的需求变更,适应合理的需求进化,我们要使用两个工具,一个工具是识别最核心需求,另一个工具是迭代演进。
- 识别最核心需求。我们要回归到最终用户。只有从最终用户的眼里看需求,才能够识别什么是最核心的需求,什么是衍生的需求,什么是无效的需求。这样,我们才能找到一个最小的子集,那就是现在就必须满足的需求。首先就必须满足的需求,是优先级最高的、最重要的事情,这些事情要小而精致,是我们的时间、金钱、智力投入效率最高的地方,也是回报最丰厚的地方。我们要把这些事情做到让竞争对手望尘莫及的地步。
- 不要一步到位。迭代演进不仅仅需要考虑上一次没有完成的事情,还要考虑变化促生的新需求。所以,在这一步,还要像第一次一样,先找到最小的子集,也就是现在就必须满足的需求。然后,全力以赴地做好它。
简单和直观,是永恒的解决方案
在软件世界里,一旦我们脱离了简单直接的原则,就会陷入行动迟缓、问题倍出的艰难境地。简洁是智慧的灵魂,我们要充分理解这一点。
我们真正要的不是简单直观的代码,而是轻松快速的行动。编写简单直观的代码只是我们为了快速行动而不得不采取的手段。有一个说法,如果面条代码能够让我们行动更快,我们就会写出面条代码,不管是刀削面还是担担面。
我见过的优秀的程序员,无一例外,都对简洁代码有着偏执般的执着。甚至小到缩进空格该使用几个空格这样细枝末节的问题,都会严格地遵守编码的规范。乍一看,纠缠于缩进空格不是浪费时间吗?可是真相是,把小问题解决好,事实上节省了大量的时间。
这些对代码整洁充满热情的工程师,会对整个团队产生积极的、至关重要的影响。这种影响,不仅仅关乎到工程进展的速度,还关系到工程的质量。真正能够使得产品获得成功,甚至扭转科技公司命运的,不是关键时刻能够救火的队员,而是从一开始就消除了火灾隐患的队员。
该怎么做到简单直观?
- 使用小的代码块。做小事的一个最直观的体现,就是代码的块要小,每个代码块都要简单直接、逻辑清晰。整洁的代码读起来像好散文,赏心悦目,不费力气。
- 遵守约定的惯例。把代码块做小,背后隐含一个重要的假设:这些小代码块要容易组装。不能进一步组装的代码,如同废柴,没有一点儿价值。而能够组装的代码,接口规范一定要清晰。越简单、越规范的代码块,越容易复用。这就是我们前面反复强调的编码规范。
- 花时间做设计。一个优秀的程序员,可能 80% 的时间是在设计、拆解和验证,只有 20% 的时间是在写代码。但是,拿出 20% 的时间写的代码,可能要比拿出 150% 时间写的代码,还要多,还要好。这个世界真的不是线性的。
- 借助有效的工具。工具有思维导图、时序图和问题清单。在拆解问题时,思维导图可以帮助我厘清思路,防止遗漏。时序图可以帮助我理解关键的用例,勾画清楚各个部件之间的联系。而问题清单,可以记录下要解决和已经解决的问题,帮助我记录状态、追踪进度。
每一行代码,都体现着程序员的修为,思考问题的深度,甚至是处理问题的习惯和态度。代码,是我们交流的语言和处世的名片。