没啥价值了,不用看了。可以用clang-tidy cpplint等开源的工具

infusion介绍

度量图

与业界项目代码相比 红色偏高,蓝色正常,绿色偏低

CYCLO 圈复杂度 FOUT 方法扇出次数
LOC 代码行 CALL 方法调用次数(扇入)
NOM method的数量 NOM method的数量
NOC Class的数量  
NOP package数量(C/C++语言中为目录的数量)  

顶部: NDD, HIT分别是指类的平均继承宽度平均继承深度

平均继承宽度: 类的继承树上,子类占所有类的比例。 默认合理范围0.2~0.6

平均继承深度: 类的继承树上,继承的层次,多棵继承树取平均值。

默认合理范围0.1~0.3

这两个指标的导向是:少用继承,用继承的时候要控制深度和宽度,减少复杂性。

软件中支持的24种代码的坏味道

编号 设计缺陷名称 编号 设计缺陷名称
1 Blob Class 13 Refused Parent Bequest
2 Blob Module 14 SAP Breaker
3 Cyclic Dependencies 15 Schizophrenic Class
4 Data Class 16 Schizophrenic Module
5 Data Clumps 17 Shotgun Surgery
6 Data Module 18 Significant External Duplication
7 Distorted Hierarchy 19 Significant Internal Duplication
8 Feature Envy 20 Significant Sibling Duplication
9 God Class 21 Tradition Breaker
10 God Module 22 Underutilized Interface
11 Intensive Coupling 23 Unnecessary Coupling
12 Message Chains 24 Unstable Dependencies

InFusion的度量是以 Size & Complexity (代码规模与复杂度)、Encapsulation(封装性)、Coupling(耦合)Hierarchies(继承性) Cohesion(内聚性)五个设计属性来度量的

###subsystems子系统类级缺陷

Cyclic Dependencies (循环依赖)

循环依赖 例如:各个子系统互相依赖形成一个或多个环。

子系统间互相依赖。编译不方便。

维护或重用(reuse)某子系统时,容易影响其他子系统

Unstable Dependencies (不稳定依赖)

不稳定依赖 例如:一个子系统(不稳定因子A)依赖另一个比它更不稳定(不稳定因子B)的子系统,A<B;判定稳定直观理解:一个系统多大程度依赖其它的系统

SAP Breakers (破坏SAP设计原则)

破坏了 Stable Abstractions Principle 稳定依赖原则

files文件级缺陷

Unnecessary Coupling (不必要的耦合)

例如:包含某个头文件,但是没有使用头文件中的任何内容。

包含了某些头文件却没有使用里面的内容。

这种不必要的包含会导致编译链接速度变慢。

Classes 类级缺陷

类型的设计缺陷只适合 C++语言。

Tradition Breaker:

子类隐藏了父类的功能。

Refused Parent Bequest:

子类不使用父类的遗产。多指两个类的继承关系使用混乱。

God Class(上帝类)

模块本身比较复杂且缺乏内聚,大量使用外部数据,控制过多外部功能

对其他模块/类的数据大量使用, 这样就破坏了模块的封装性

往往集中了许多模块的功能函数,从而加大了代码的耦合。

坏处是往往模块大而复杂,内聚性差,从而不好维护。

Data Class(数据类)

纯数据结构(c文件/c++为类),与功能的封装不紧密。

Blob Module:模块(c文件/C++类)有很多大而复杂的函数,关注模块内部的内聚和复杂性

Blob class(复杂类)

巨大臃肿的函数/文件/模块/类,都是糟糕的设计。

简言之,就是规模过大,圈复杂度过高,嵌套层次太深。

Modules 模块级缺陷

Data Module (数据模块)

纯数据结构(c文件/c++为类),与功能的封装不紧密。

Blob Module:模块(c文件/C++类)有很多大而复杂的函数,关注模块内部的内聚和复杂性

God Module (上帝模块)

全能(上帝)模块(c文件)。 模块本身比较复杂且缺乏内聚,大量使用外部数据,控制过多外部功能

对其他模块/类的数据大量使用, 这样就破坏了模块的封装性

God Class God module往往集中了许多模块的功能函数,从而加大了代码的耦合。

God Class God module坏处是往往模块大而复杂,内聚性差,从而不好维护。

Schizophrenic Module (紊乱的模块)

紊乱的模块。一个模块提供几组完全不相关的接口,接口没有按照功能进行内聚。

对代码模块或类的设计来说,好的风格应该是低耦合,高内聚。

模块内部应该功能单一。

如果一个模块或类实现了多个不同的功能,比如处理界面的模块又处理了很多业务相关功能,

那理应把它分成几个功能单一的类

Underutilized Interface(未用到的接口)

接口未被充分利用。 例如:一个模块有很多全局函数,但是有一半以上没有被其它模块使用。

模块提供的接口,即全局函数,没有被其他模块使用。

其他模块不使用的接口,不建议‘预先提供’

由于在C语言里,函数默认都是全局函数(允许外部模块调用),

所以公司很多C代码里的模块有很多内部使用的函数,却被认为是‘没被使用’的‘接口’。

这种情况可以忽略。

Significant Sibling Duplication (兄弟类中的代码重复)

同父类的子类之间的方法重复度很高

Functions 方法级缺陷

Blob Operation:(复杂的函数)

函数过于复杂

Data Clumps(数据泥团)

相似的函数参数列表,多次传递,没有封装成一个结构

数据虫。 比如这几个函数,可以看到几个参数总是共同出现。

可以想到,这几个参数间之间一定有内在的联系。

存在内在联系,则应该将这些参数封装在一起组成类或者结构。以类或者结构为传递的参数。

另外,参见《代码整洁之道》,函数的入参应该尽量少。

在业界大师看来,动不动3个4个以上的入参实在是太多了。

Feature Envy(特性依恋)

函数很少访问自己模块的数据,总是访问外部模块的数据。

Classes and modules 应该封装 data and the operations在一起

如果一个module里的函数总是访问其他module里的data ,

那就是这个函数没有和本module的数据封装在一起,违反了原则。

按照封装的原则,应该把这个函数移到他经常访问的那个module里面去。

Intensive Coupling(高耦合)

一个方法访问了很多其它的外部类或模块,同时调用这些类或模块的的方法很少

根据封装内聚的原则,模块之间应该低耦合,联系应该通过接口来完成。

Significant Internal Duplication(内部代码重复)

类或模块内的方法的重复度很高

Significant External Duplication(外部代码重复)

类或模块之间方法的重复度很高

Shotgun Surgery (散弹式调用)

修改一个问题,需要同时修改多处代码;散弹式的

Message Chains:(消息链)

需要经过多次的中间的传递和调用才能获得需要的数据,句柄、中间变量传递过多