《程序员修炼之道》 -- 务实的方法(上)

本文最后更新于:2020年5月20日 晚上

前言

周五啦,忙碌了一个星期,趁着周五晚上听听轻音乐,看会书,写写感想,放松一下~

《程修道》在第一章由务实的哲学开头之后,在接下来的第二章就开始讲务实的方法,即由思想理念操作实践的过程。

务实的方法总共有8部分,优秀设计的精髓DRY-邪恶的重复正交性可逆性曳光弹原型与便签领域语言估算

第二章的内容很丰富也更需要深入去阅读品味,今晚先记录一部分。

优秀设计的精髓

这一部分,可以说是触及软件开发核心的至关重要主题,后面的7部分内容,都是由此来进行更为详细的展开。

优秀的设计比糟糕的设计更容易变更。我们在日常经常有谈到怎样设计好的软件,最后总的概括,能适应使用者的就是好的设计。对于我们的代码而言,就是要顺应变化,这个顺应变化怎么理解呢,书中提到了一个重要的原则ETC(Easier To Change)原则:更容易变更。很多设计原则,基本都是ETC原则的特例。

为什么代码要解耦,因为通过隔离关注焦点,可以让每一部分都容易变更。

为什么单一职责原则很有用?因为一个需求变化仅体现为某个单一模块上的一个对应变化。

为什么良好的命名规则很重要?因为好的命名可以使代码更容易阅读,而我们必须先通过阅读之后才能做变更。

ETC应当是一种价值观念,而不是一条规则。价值观念跟规则的区别在于,规则是用来规范大家的行为,是要遵守的,有一种被动、甚至是束缚的感知。而价值观念是一种思维向导,它会帮助我们去思考,去做决定:哪些是该做的,哪些是不该做的。我们应该把ETC当成跟其它的价值观念一样,像“八荣八耻”,让它漂浮在我们的思维当中,当我们开始思考做决定时,它能微妙地将我们推向正确的方向。

怎样做到将ETC作为价值观念?作者给出了他们这些年总结的一些经验:一开始需要一点有意识的强化。我们可能花几个星期的时间来有意识地问自己:“刚刚做的代码设计是让整个系统更容易变更还是更难改变?”。当我们提交代码的时候问一遍,写测试的时候问一遍,当我们修复BUG的时候再问一遍,甚至要反思这个BUG的出现是不是可以通过更好的设计来规避。

更进一步。除了上述作者给出的经验建议,我们还可以做得更好。第一点是让我们的代码坚持保持解耦内聚、让我们的代码容易替换,即我们常说的可配置化。可配置化的好处就是不管以后有什么需求改变,我们都可以较为容易地去变更,而无需花费精力去重写。第二点是培养直觉,要经常记录我们遇到的问题、可以做的选择、可以怎样改变的猜测,以便我们可以进行快速的回顾和反思,下次遇到同样的问题,可以在脑海里快速提炼出方案。

正交性

正交性”是从几何中借用来的术语:若两条直线相交成直角,它们就是正交的。用向量术语来说,这两条直线互不依赖。在计算科学中,正交就代表独立性或者解耦性

消除不相关事物之间的影响。组件化这个概念在如今已经是一个普遍的概念,很多大厂也都有开源的组件库。我们在写组件的时候,都是希望我们的组件是独立自主,有单一、清晰的定义,能够简单、重复地使用。当我们变更某一个组件的时候,不会对其它组件有很大影响甚至是没有影响。从这角度来看,正交性的系统主要有两个方面的好处:提高生产力以及降低风险

提高生产力

  • 正交的方法促进了复用。前端组件化最基本的定义,就是组件都是职责明确定位清晰的,像表格组件、时间选择组件等等,根据不同的职责,能够跟不同的组件进行搭配复用。越是低耦合,我们需要重新配置和变更的地方就越少,也就越容易进行。
  • 节省开发、测试时间。

减少风险

  • 代码中“生病”的部分被分隔开。如果一个组件出问题了,我们只需改动组件某个部分,减少大幅改动的风险。
  • 系统更加稳健。这样的系统,就像天气预报一样,局部有阵雨,局部多云一样,哪一块“天气不好”,我们只需对特定的部分修复,不会对系统造成影响。
  • 更有意思的一点,就是不会受特定供应商的束缚。我们的系统可能会对外对接一些特定的服务,那这些服务我们更应该遵从正交性,最好将对接的这部分独立,以后供应商改了啥东西,我们也照样只是更改独立的这部分就OK了。

可逆性

如果某个想法是你唯一的想法,那就没有比它更危险的东西了。 ——埃米尔-奥古斯特-沙尔捷

可逆性跟上面的正交性有点相似,正交性强调独立解耦,可逆性是可逆容易改变,两者之间存在一定的联系。

我们在生活中都喜欢简单、唯一的解决方案,甚至有时还会严重依赖某些事实,但这在某种程度上是很危险的。

变化不需要多么剧烈,甚至不必立刻发生,随着时间推移还有项目的演进,我们可能会发现很难前行,甚至陷入无法立足的困境,每当做出一个关键决定,我们就会投身于更具体的目标,由于选择变少,视野会越来越窄。但是问题在于,关键的决定一般不容易逆转

所以为了做到可逆性,我们要坚持做面向有弹性、适应性强的编程,像解耦,做外部配置,组件化,模块化等等,错误在于认为任何决定都是板上钉钉,而没有为可能出现的意外或者变更做好准备。

现实中我们也不可能为今后会出现的各类架构提前做好准备,我们能做的,就是在变化来临时修改能更容易一点,而不是每次面临巨大的变化,脑海里只有一个念头:重构、重写