软件构造学习笔记——代码异味

    xiaoxiao2025-07-13  18

    代码异味code smell

    代码异味(卫生)Code "smells"(hygiene)重复的代码:过长的方法:庞大的类:长的参数表:不同方向的变化:霰弹式修改依恋情结 Feature Envy:数据堆积:基本类型迷恋(primitive obsesstion)Switch语句:平行继承层次:冗余类:暂时的字段消息链:中间人:过度亲密:具有不同接口的替代类(Alternative Classes with Different Interfaces)不完全的库类(Incomplete Library Class)数据类:拒绝遗赠:注释:

    代码异味(卫生)Code “smells”(hygiene)

    代码异味是经常会对应于系统中深层次的问题的表面迹象。

    重复代码

    过长方法

    庞大的类

    长参数表

    不同方向的变化

    霰弹式修改(shotgun surgery)(改一个地方得改其他地方)

    shotgun surgery是软件开发中的反模式,发生在开发人员向应用程序代码库添加功能的地方,这些代码库在单个更改中跨越多个实现者或实现。

    依恋情结:(feature envy):标志和症状:方法访问另一个对象的数据而不是其自己的数据。问题的原因:字段移动到数据类后可能会出现这种smell。

    数据堆积(Data Clumps)

    基本类型迷恋(primitive obsesstion)

    Switch语句

    平行继承层次(Parallel Inheritance Hierarchies)

    冗余类(Lazy Class)

    暂时的区域(temporary field)

    消息链(message chain)

    中间人(middle man)

    过度亲密(inappropriate intimacy)

    具有不同接口的替代类(Alternative Classes with Different Interfaces)

    不完全的库类(Incomplete Library Class)

    数据类(Data Class)

    拒绝的馈赠(Refused Bequest):子类并没有用到很多被继承的成员

    注释

    重复的代码:

    有不止一处的相同的代码结构(源于代码复制)

    因为你修改一处重复的代码而不能同时修改其他的,这很糟糕,你可能会引入bug

    过长的方法:

    过长的方法很难去理解;

    许多简短方法的性能问题在很大程度上已经过时了

    庞大的类:

    类致力于减少聚合

    经常会出现很多实例变量

    长的参数表:

    很难去理解,有时可能会变得不一致,很难去使用

    不同方向的变化:

    和聚合(cohesion)有关

    症状:一种类型的更改需要更改一个方法子集; 另一种类型的更改需要更改另一个子集(由于不同的原因,一个类通常以不同的方式更改)。

    霰弹式修改

    每次修改一次,你不得不对不同的类做出很多的小的修改;

    很难去认证和做出彻底的修改

    依恋情结 Feature Envy:

    一个方法看上去对另外一个类更加有兴趣,而非自己所在类(例如,把很多个getter()方法在另一个对象里面去计算数值)

    数据堆积:

    一串串的数据,束在一起。例如:几个类中的字段,许多方法签名中的参数。

    基本类型迷恋(primitive obsesstion)

    代码使用内部建类而不是应用类

    结果:减少不可理解性,过长方法,重复代码,增加复杂性

    Switch语句:

    经常的,你发现一样的switch语句将一个程序分解成到了不同的地方,如果你增加一个新的子句给switch,你不得不找到所有这些switch语句,并且修改他们。

    平行继承层次:

    霰弹式修改的一个特殊的例子就是:每次你编写一个类的子类的时候,你也得不得不去写另外一个类的子类

    冗余类:

    一个类不再起到足够作用,引起你的注意。

    例子:可能是类被之前的重构缩小,也可能是表示计划中的功能,却并未起作用。

    暂时的字段

    对象的属性直再特定的环境下被设置,但是对象应该需要所有它的属性

    消息链:

    当一个用户通过一个类访问另一个类时,然而它之后还会访问另一个类,一直这样下去。

    用户被耦合至传递的结构。任何对中间关系的改变都会导致用户不得不改变其他。

    中间人:

    一个类的绝大多数方法都为人给了另外的这个类

    过度亲密:

    类变得过于亲密,并在相互的私有部分花了太多的时间去搜素

    具有不同接口的替代类(Alternative Classes with Different Interfaces)

    两个类表现的完全相同,但是却有不同的方法名

    原因是:创建这种类的程序员可能不知道已经有一个功能等价的类存在了。

    不完全的库类(Incomplete Library Class)

    迟早的,库不再能满足我们的需求了,唯一的解决办法——更改库文件——一般不太可能源于类的只读性

    库的作者并没有提供你需要的功能,或者拒绝去实现他们

    数据类:

    这些是拥有字段的类,为字段编写方法,仅此而已。他们是数据的保存者,但是对象应当是有关于数据以及行为。

    拒绝遗赠:

    一个子类忽略绝大多数他从父类继承的功能

    子类可能通不过“IS-A”test

    注释:

    注释有时候被用来藏匿不好的代码

    最新回复(0)