3. 优雅代码原则

总体介绍

在讲解一些具体方法之前,我们需要先了解一下软件开发的通用原则,便于从宏观角度把控开发的质量。后续讲到的每个开发技巧,其实背后都隐藏着以下的这些设计思想,通过了解他们,方便我们举一反三,以不变应万变。

Software Entropy 软件熵

物理学中有熵增定律:“在一个孤立系统中,事物总是自发、不可逆的朝着熵增加(混乱)方向进行。当熵达到最大值时,系统就会出现严重混乱,最终走向灭亡。”一个典型的例子就像我们住的房子如果长期不进行清理,就会导致越来越杂乱,最终完全不适合居住。

软件熵的定义,借用物理学概念,描述的是代码的混乱程度。它告诉我们,随着软件需求的不停变更,原本的设计方案将不再适用,如果不对代码进行定期清理与优化,软件的熵一定会增加,代码会开始腐化并散发着各种怪味道,最终导致项目无法被人类维护,从而被废弃掉。

之所以先提到这条原则,因为理论上我们做的任何代码优化技巧,本质都是在降低软件熵。比如说,我们常常用到的 “松耦合,高内聚”的设计思想。这种思想鼓励我们,将关联度高的代码放在尽量靠近的地方,将关联度低的代码放在不同的地方,便于管理。我们在整理家务的时候也借用类似的思想,将顺手的工具摆放在一块,方便使用(比如说把所有的清理工具摆放在统一的隔间里面);将不同的房间划分不同的功能,避免相互影响(比如厕所马桶坏了,不影响我们卧室的功能)。这些都是为了降低整个系统的混乱程度,也就是在降低整体的熵。

软件开发是一门管理复杂度的艺术。业务逻辑的复杂度 并不一定会导致软件熵上升。对于一些很复杂的项目,比如Linux Kernel,因为开发者非常注重代码质量,反而能够维护得井井有条。我们需要做的就是把代码逻辑进行解耦合,是不同的逻辑可以放在不同的模块进行单独维护,模块之间不会相互影响,如果有些模块比较复杂我们可以划分给专门的人员进行维护。如果我们能做到这点,理论上代码项目可以在支撑非常高的业务复杂度的情况下,依然能够非常高效的维护。

因此,熵增原则告诉我们以下三点最重要的思想:

  1. 软件不定期清理,一定会腐化。
  2. 我们做的任何代码优化技巧,都是为了降低软件熵。
  3. 软件开发是一门管理复杂度的艺术,如果项目维护管理得当,软件可以支持非常高的业务复杂度。

Broken Window Effect 破窗效应

破窗效应指的是,如果一栋大楼有一扇窗户开始破了,但是管理人员没有及时修缮,那么整个大楼的其他窗户也会逐渐开始坏掉。这是因为不及时修缮第一扇破了的窗户,体现了管理人员在大楼整体管理上的疏漏以及对于大楼整体管理质量的松懈态度。

在软件开发中,破窗效应指的是,当代码出现第一个质量问题的时候,维护者没有及时修复或者表现出不在乎的态度,这也会鼓励其他开发者不重视代码质量,从而导致整个项目的代码质量开始迅速降低。这个就像是温水煮青蛙,虽然最开始出现的问题很小,但是大家没有及时重视,等到后面问题逐渐扩大的时候,大家也缺乏感知问题严重性的敏锐觉察力,最终直到问题变得不可避免,无法收场。

破窗效应 告诉我们

  1. 作为项目的维护者,如果代码出现了质量问题,不管多小,都需要及时修复,并且要向所有的开发者明确展示出对于代码质量的重视程度。
  2. 勿以恶小而为之。问题始于微末,很多大的代码质量问题,都是从一些很小的,不起眼的事情开始的。

Boy Scout Rule 童子军原则

童子军里有一个规定:“离开的时候,总要让露营地比你来的时候更干净。” 如果你在地上发现脏乱,把他收拾了,无论是谁造成的。要刻意地为后面来露营的人创造更好的环境。实际上这条规定最原先是童子军之父——Robert Stephenson Smyth Baden-Powell——写的,原文是“努力让世界比你遇见它的时候更美好一点”。

这个方法也可以应用到代码编写上。每次我们开发一个新功能,或者修复一个bug的时候,我们应该花费一些努力使得code base比上次干净整洁一些。让所有的开发者养成这种意识很重要,因为积少成多的作用是巨大的。所以我在一般在提交代码之前,都会认真检视代码并询问自己,我新提交的代码是否让整个项目更加杂乱,或者更加干净了。如果答案是前者,我就会重新优化代码,使其更加干净整洁。

童子军原则是 破窗效应的反面。如果说破窗效应是告诫大家,勿以恶小而为之;那么 童子军原则 就是劝慰大家,勿以善小而不为。破窗效应指的是每个人都缺乏代码质量意识,每次变更都造成代码更加杂乱一些,最终让整个项目进入无法维护的程度。而童子军原则是每个人保证代码比上次干净一些,久而久之项目代码质量和可维护性就会提升一个维度。积小成多,水滴石穿。小小的意识不同,最终却能最终完全相反的结果,所以我们不应该不重视。

童子军原则告诉我们:

  1. 每次提交代码之前,认真检视代码并询问自己,我新提交的代码是否让整个项目更加杂乱,或者更加干净了。如果答案是前者,请重新优化代码,使其更加干净整洁。
  2. 勿以善小而不为。养成代码质量的意识很重要,他可能不会花费你很多时间,但是积少成多的力量会造成很大的改变。

The Two Hats 两顶帽子原则

《重构》这本书的作者之一 Ken Beck 对开发过程中的代码优化方式,总结出了两顶帽子的比喻。在代码编写过程中,我们把时间分为2部分,增加新功能 和 做代码优化,这就像两顶帽子一样。当我们 带上 增加新功能的帽子的时候, 我们专注于代码的功能性,就不会去考虑代码的优雅性,主要目的是让代码执行结果满足期望;当我们带上代码重构的帽子的时候,我们专注于代码的质量,我们不增加新的功能代码,而是致力于让现有的代码结构更加合理,清晰与优雅。

我们在开发过程中可以经常切换这两顶帽子。当最开始开发功能的时候,我们写各种单元测试以及功能性代码逻辑,尽快使得代码满足产品需求;但是当我们发现新功能的代码虽然能工作,但是很丑陋的时候,我们可以停下来,换上另外一顶帽子,将代码优化到一个相对可以接受的程度。我们在开发过程中不停地换这两顶帽子,这种切换的时候可能很短,比如说十多分钟换一次。而新的代码就在增加新功能 与 提高代码质量 这两条路上并肩前进,并最终达到目标。

为什么要使用两顶帽子的开发方式呢? 因为它使得我们的工作更高效。一方面,两顶帽子使得我们在不同的时间切换不同的思维角度,从而专注于当前的事情,而不用同时考虑两件事情。另外一方面,两顶帽子是相互助益的,实现代码功能性的帽子是我们写新代码的出发点与最终目的,而代码重构能通过优化代码结构提高代码的可读性/可维护性,从而帮助我们更加高效的实现功能性代码。

两顶帽子都是代码开发中的重要一环,不可偏颇。有人倾向于所有代码完成之后才做代码优化,但是往往发现需要优化的代码太多,被巨大的工作量吓得望而却步了。所以倒不如我们在开发过程中就开始提前做这样子的工作。通过这种渐进式,灵活的代码开发方式,我们能够在早期就开始做代码优化,这样子效果往往更好。

两顶帽子原则告诉我们:

  1. 开发过程中可以灵活地切换两顶帽子,在代码的功能性与优雅性之间进行权衡,这使得我们的开发更加高效。

Progressive Improvement 渐进式代码优化

代码优化应该是渐进式的,而不是断崖式的。所谓断崖式指的是等到代码腐化到无法接受或出现重大故障的时候,程序员跟项目组申请花费较长时间(比如说几个月)来重构代码,在此期间代码无法增加任何新功能,并且不能马上可用。但更加正确和高效的方式是,应该有计划性一点一点进行渐进式代码优化(业界也称之为微重构),在此期间,代码可以持续可用,并且可以增加一定的新功能。

为什么我们倾向于渐进式代码优化呢? 因为

  1. 它通过较长的时间周期和完善测试,使得风险可控。
    1. 软件故障一般都来源于变更,而大的变更带来大的故障风险。
    2. 通过更长时间的测试来逐渐验证我们的每一步变更造成的影响,提前发现问题。
  1. 它使代码处于持续可用的状态,对于产品团队更容易接受。
    1. 软件只有处于可用的状态,才能创造价值。如果说因为要做代码重构而造成较长时间无法使用,对于大部分产品场景都是不可接受的。
  1. 它降低了重构的难度,对于开发者更容易接受。
    1. 大的变更总是让人望而生畏,不仅是巨大的工作量和紧张的时间表,还有大的变更造成大的软件风险。
    2. 没有渐进式优化,程序员需要花很多精力跟领导解释花较大时间的精力进行重构而服务不可用的原因(一般领导和产品团队都很难同意这样子的诉求)。
    3. 多方面的原因都会导致 程序员一般倾向于不去做代码重构,除非到了万不得已的情况下,但那个时候才做重构已经晚了。

代码出现巨大的质量问题,绝非短时间造成的,而是长期对于代码质量的忽视,不负责任的编码态度,不合理的时间安排等各方面因素的综合作用导致的。要想解决巨大的质量问题,短时间肯定是不行的,我们需要有耐心。

渐进式代码优化告诉我们

  • 有问题,慢慢修;每次做一点,日久见良效。
  • 当你下次发现项目组计划花费很长的时间做重构的时候,需要警惕,建议你们考虑下渐进式优化的方法论。
  • 完善的单元测试覆盖率,也是重构非常重要的一环,在开始前请确保你的单元测试可以正常工作。

Refactoring and Performance 重构与性能

软件开发中最重要的一点原则就是 避免过早优化,因为它有可能引入不必要的复杂度。在工作当中,如果遇到代码优雅性 与 性能 之间的抉择,我大部分时间都会毫不犹豫地选择选择保证代码优雅。原因是

  1. 很多情况下,我们对于性能的担忧是多余。
    1. 比如说代码里面多了几次循环,或者增加了几个新的变量,这些对于代码整体的效率影响是微乎其微的。
    2. 即使需要做性能优化,我也会进行实际测试,基于明确的测试结果来进行针对性优化,因为有数据支撑更加有说服性
  1. 优雅的代码,更加容易被优化。
    1. 优雅的代码是解耦合的,更加容易定位性能瓶颈,并对其进行针对性优化,不用担心影响到其他模块
    2. 优雅的代码更容易被修改,所以更方便开放者增加一些性能优化的代码逻辑。

DRY 原则

DIY代表 Don‘t Repeat Yourself。

重复是是万恶之源。当你不知道很多花哨的代码优化技巧的时候,就记住一点,尽量减少重复代码,通过抽象通用的函数等方式,来提高代码的复用率,这就能起到很大的帮助。因为重复的代码会带来很多问题,比如说增加了软件开发人员维护工作的心智负担;每次修改重复的代码,都需要修改所有重复的代码片段等等。

总结

以上讲解了我们在软件开发中,常常需要用的通用原则,大家了解一下即可,如果没有理解也没有关系,接下来我们会通过介绍具体的代码优化技巧,来讲解如何写出优雅的代码,便于加深大家对于以上原则的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值