知识卡片

代码坏味道的三层分类体系

普通读书笔记卡

内容

面向对象程序中可能出现的代码坏味道可以按作用范围分成应用级、类级、方法级三层,这个分层本身就是一种诊断线索——同样是”代码写得不好”,问题出现在哪个粒度层次,直接决定了该用哪种重构手法去修。应用级坏味道关注跨函数/跨类的结构问题:重复代码(同一表达式在多处出现,用提炼方法Extract Method消除,若分布在父子类间则再配合上移方法Pull Up Method)、人为复杂性(简单问题却套用了复杂设计模式)、散弹式修改(一种变化牵连多个类都要改,与”分散变更”互为镜像——分散变更是一个类被多种变化影响,散弹式修改是一种变化引发多个类修改,两者的整理方向都是让”外界变化”与”需要修改的类”趋于一一对应,用移动方法/移动域把相关代码收拢到同一个类)。类级坏味道关注单个类内部的职责边界:过大的类(塞了太多实例变量,用Extract Class拆分)、依恋情结的类(某个方法对别的类的数据兴趣远高于自己所在类,用Move Method搬过去)、过度亲密类(两个类互相探究对方private成分,用Move Method/Move Field划清界限,或用委托机制斩断双向关联)、拒绝的馈赠(子类只想复用父类部分代码却继承了整个接口,若继承本身没有意义就消除继承,若只是不想暴露父类接口则改用委托而非乱改继承体系)、冗赘类(所得不值维护成本,用崩溃层次结构或内联类消除)、数据泥团(几项数据总是绑在一起在多处出现,说明它们该有自己的对象,用Extract Class提炼、再用参数对象为超长函数签名减肥)、不完美的程序库类(库不好改但又不能碰源码,改一两个方法用引入外援方法Introduce Foreign Method,加一堆行为用引入局部扩展Introduce Local Extension)、幼稚的数据类(只有字段和存取方法的”不会说话的数据容器”,被其他类过度操控,用封装字段/封装容器/移走设置方法收紧边界)。方法级坏味道以过长方法为代表——书中给出一个具体判断阈值:超过10行就该警惕,函数代码行原则上不超过100行;过长方法的典型成因是”我就加两行代码,专门建方法太小题大做了”这种日积月累的心理,最终演变成无人能看懂、也无人敢动、只能继续往里加代码的恶性循环;识别技巧是找注释——如果一段代码前面需要写注释解释”这段在干什么”,说明这段代码本身就该被提炼成一个用注释内容命名的独立函数,哪怕只有一行。另外参数太多、超长/超短标识符、数据过量返回、超长代码行也属于方法级坏味道。

参考来源

- 位置:《软件架构理论与实践》第20章《软件架构坏味道》"20.2 典型的代码坏味道"节(源文件:_epub-src/OEBPS/text00170.html) - 结论依据:原文明确"把面向对象程序中可能出现的代码坏味道分成应用级坏味道、类级坏味道和方法级坏味道三种类型",并逐项给出每种坏味道的定义、成因和对应重构手法(如"运用Move Method把它移到适当的地方""对于任何超过10行的方法,你就可以考虑其是不是过长了"),直接支撑本卡片结论。 - 原始内容:一般来说,对于任何超过10行的方法,你就可以考虑其是不是过长了。原则上函数中的代码行数不要超过100行……大部分人都觉得:"我就添加这么两行代码,为此新建一个方法实在是小题大做了。"于是,张三加两行,李四加两行,王五加两行,方法日益庞大,最终再也无人能完全看懂了。