这一节,我们要制定技术债务的分类标准,为后面的技术债务梳理,提供依据。
技术债务出现的根本原因,是为了及时上线做了妥协,使用了不合理的实现方案。
梳理技术债务,我们首先需要明确什么是合理的实现方案,即什么是高质量的代码。
《Sonar code quality testing essential》一书中从七个维度定义了代码的这种内在质量,Sonar开发团队上纲上线的戏称为开发人员七宗罪:
参考:代码质量与技术债
《重构》一书列出了代码的24种坏味道,及其对应的重构方法。
神秘命名(Mysterious Name)
重复代码(Duplicated Code)
过长函数(Long Function)
过长参数列表(Long Parameter List)
全局数据(Global Data): 全局数据的问题在于,从代码库的任何一个角落都可以修改它,而且没有任何机 制可以探测出到底哪段代码做出了修改,又难以定位bug。
可变数据(Mutable Data) :对数据的修改经常导致出乎意料的结果和难以发现的bug
发散式变化(Divergent Change) :一个变化导致多处代码修改,让需求变更之后的修改变的困难。
霰弹式修改(Shotgun Surgery) :遇到变化,需要在代码种进行多处细小的改动,修改时很容易漏掉。
依恋情结(Feature Envy) :一个函数与另外一个模块中的函数或数据交互的格外频繁。
数据泥团(Data Clumps) :类中的某些字段总是成组的出现,这些字段应该有属于自己的类。不要建大而全类。
基本类型偏执(Primitive Obsession) :用基本类型来代替,金额,坐标,重量这些数据。重构方式是,使用对象包装这些基本类型。
重复的switch (Repeated Switches) :在不同的地方反复使用同样的switch逻辑,的问题在于:每当你想增加一个选择分支时,必须找到所有 的switch,并逐一更新。
循环语句(Loops) :管道操作可以帮助我们更快地看清被处理的元素以及处理它们的动作
冗赘的元素(Lazy Element) :过度的封装,将简单到方法名称几乎和实现一样的方法提炼成方法,或将一个简单的方法独立成类。重构方式是:内联函数 (115)或是内联类(186)
夸夸其谈通用性(Speculative Generality) :设计和增加了一些自认为未来可能用的上的功能,企图以各式各样的钩子和特殊情况来处理一些 非必要的事情,让代码变的复杂。
临时字段(Temporary Field) :其内部某个字段仅为某种特定情况而设。这样的代码让人不易理解。重构方式是:使用提炼类将这些为某些特定情况而增加的字段独立出去,同时将相关的函数也搬移出去。
过长的消息链(Message Chains) :消息链指链式调用,例如用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象。
中间人(Middle Man) :某个类的接口有一半的函数都委托给其他类就是过度运用委托。
内幕交易(Insider Trading) :对于模块之前不可避免的数据交换都应该放在明面上。
过大的类(Large Class) :大类往往出现过多的字段,重复的代码就不可避免。类内如果有太多代码,也是代码重复、混乱并最终走向死亡的源头。
异曲同工的类(Alternative Classes with Different Interfaces)
纯数据类(Data Class) :一个类仅有一些字段和读写这些字段的方法,除此之外没有其他东西。
被拒绝的遗赠(Refused Bequest) :子类不应该继承他们不需要的数据和方法。尝试使用组合重构
注释(Comments) :如果需要注释来说明一块代码了做什么,或者是需要解释其行为,说明需要用提炼函数或者改名函数声明来重构。
结合上文的对软件质量的评估标准。
我们结合自己的实际需求,大致可以把技术债务分类成以下几类:
这一节制定标准,明确哪些技术债务需要治理,治理时机是什么时候。
《重构:改善即有代码的设计》
《代码整洁之道》