infusion介绍
没啥价值了,不用看了。可以用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:(消息链)
需要经过多次的中间的传递和调用才能获得需要的数据,句柄、中间变量传递过多