前言
最近读Robert C. Martin(Bob大叔)的书《敏捷软件开发》,准备围绕这本书开一个专题来写点读书总结。本文是这个专题的第三篇。
设计模式有六大原则:单一原则;里氏替换原则;依赖倒置原则;接口隔离原则;迪米特原则;开闭原则。软件腐化可以理解为是设计模式六大原则的对立面。
当软件出现以下七种特征之一时,就说明软件正在腐化:僵化性(Rigidity)、脆弱性(Fragility)、牢固性(Immobility)、粘滞性(Viscosity)、不必要的复杂性(Needless Complexity)、不必要的重复(Needless Repetition)、晦涩性(Opacity)。
不必要的复杂性(Needless Complexity)
原文
为过多的可能性作准备,致使设计中含有绝不会用到的结构,从而变得混乱。一些准备也许会带来回报,但是更多的不会。期间,设计背负着这些不会用到的部分,使软件变得复杂,而且难以理解。
不必要的重复(Needless Repetition)
原文
复制(Copy)和粘贴(paste)也许是有用的文本编辑(text-editing)操作,但是它们却是灾难性的代码编辑(code-editing)操作。当系统中有重复代码时,对系统进行改动会变得困难。在一个重复的代码体中发现的错误必须要在每个重复体中一一修正。不过,由于每个重复体之间都有细微的差别,所以修正的方式也不总是相同的。
我的理解
假设,现在有一个河北地区的某报表统计接口(接口一),接下来还需要开发一个山东地区的接口(接口二),逻辑与河北地区一样,只是数据源切换一下。
于是开发人员把河北统计接口代码粘贴一份出来,稍微修改涉及到数据源部分的代码,就新开发出一个新的山东统计接口。
接下来的几个省,也是类似。
某一天,我们发现刚开始的接口里有一个Bug,于是我们需要去把所有接口的Bug一一处理一遍。
又某一天,我们又发现刚开始的接口里有另一个Bug,我们还是去一一处理。处理到了第三个接口时,我们发现,第三个接口的数据源本身比较特殊,用和第一个第二个接口Bug同样的处理方式处理不了,我们得针对第三个接口的数据源做另一种特殊处理,才能处理第三个接口的Bug…
还是上面的这一天,我们处理第四个接口的Bug,发现第四个接口的数据源更特殊,得去找开发第四个接口的小四来处理,因为他粘贴完代码后,还做了很多(不止一点点)针对第四个接口数据源本身的特殊处理…
于是,我们约定,遇到类似情况,谁粘贴的代码,谁负责处理Bug,小四处理接口四的代码,小五处理接口五的Bug,虽然这些Bug都来源于小一开发的接口一的那个Bug。
于是,大家有点抱怨小一,而小一更是一脸委屈…
又过了几天,我们需要修改接口一里面的一个枚举,但是,由于其他接口都复制粘贴的接口一的代码,现在所有接口都在用这个枚举,而小一最初设计接口一(即:河北地区的某报表统计接口)的这个枚举就是为了针对未来河北地区可能发生的业务变化进行扩展的…领导责怪小一的代码扩展性差,每一次做一个小的改动都需要花很久的时间,小一委屈至极,他明明从一开始就已经考虑到扩展了…
晦涩性(Opacity)
原文
晦涩性是指,代码模块难以理解。当开发人员最初编写一个模块时,代码对于他们来说看起来也许是清晰的。这是由于他们使自己专注于代码的编写,并且他们对于代码非常熟识。在熟识减退以后,他们或许会回过头来再去看那个模块,并想知道他们为什么会编写出如此糟糕的代码。
我的理解
说起晦涩性(Opacity),必须吐槽一下写代码时遇到的最头疼的一件事,就是去修改那些代码很长的存储过程脚本。尤其是那种充满着各种语法倒装、语句拼接、临时表滥用、不缩进不对齐、不写注释的存储过程。