多个常见代码设计缺陷

 0、前言

  在软件设计开发中,代码的设计都体现在:子系统与子系统、模块与模块、函数与函数之间的关系,设计越糟糕的软件,维护成本越高,质量也往往难以达标和称赞。

  好的设计必定是:层次关系简洁、清晰、易维护和扩展的。

  不会研究太高深的设计,只总结出一些常见的代码设计缺陷,这些设计缺陷如能很好的解决和避免,相信代码能力(编写、设计、评审、重构)能提高一个档次。

  主要介绍下面15个常见代码设计缺陷:

  1、复杂函数(Blob Operation)

  缺陷特征:指的是代码行多,分支嵌套深,变量多,参数多,注释多,复杂度高等特征的函数。

  缺陷影响:函数不易理解和维护,代码重复、冗余。

  解决方法:新开发代码时,函数都是越写越复杂的,应该要有意识地、积极地去分解提炼成小函数或独立功能的函数,甚至当感觉需要以注释来说明点什么的时候,这时其实就应该独立成一个函数。函数建议值:代码行24,if语嵌套深度6,圈复杂度10,功能应该单一。

  2、数据泥团(Data Clumps)

  缺陷特征:函数的参数多且参数列表相似,反复调用相同的参数列表。

  缺陷影响:大量重复,影响编译的效率;参数多,很难理解和调用。

  解决方法:参数列表应该封装成结构。建议值:函数参数平均为2,避免5个以上。

  伪码示例:GetDate(int year,int month,int day,int time) -> GetDate(struct DateRange)。

  3、不必要的耦合(Unnecessary Coupling)

  缺陷特征:包含某个头文件,但是却没有使用头文件中任何内容。

  缺陷影响:编译链接速度慢,耦合度高,头文件错误包含,如包含某个头文件却没有使用里面的内容,某个头文件却依赖某个dll,则会引起不必要的dll依赖和错误。

  解决方法:头文件不能乱包含,100%确认每个包含的头文件使用情况,删除不必要包含的头文件。

  4、过度耦合(Intensiue Coupling)

  缺陷特征:一个函数调用大量其它模块的函数,却调用很少本模块的函数。

  缺陷影响:一个函数与多个函数(这些函数属于少数一两个类)联系过于紧密;一个类提供了很多函数给外部某个函数调用;耦合度高,类不够抽象。

  解决方法:识别内、外部模块函数,外部模块要足够抽象调用。

  5、循环依赖(Cyclic Dependencies)

  缺陷特征:多个子系统处于一个环状互相依赖关系里面;函数的调用关系混乱、循环;文件直接或间接交叉引用。

  缺陷影响:不易理解和维护,编译慢,关系混乱,重用困难。

  解决方法:多文件或系统间要划分清楚结构、层次关系,应做到无环依赖。

  伪码示例:循环包含头文件,file A包含file B,而file B又包含了file A。

  6、依恋情节(Feature Envy)

  缺陷特征:函数很少访问自己模块数据,总是访问外部模块数据;访问自己模块少,访问其它模块多;数据和操作不在同一模块;对其它类的数据比较感兴趣。

  缺陷影响:耦合度高。

  解决方法:同一模块的数据和操作应该放在一起。

  7、重复代码(Repeat code)

  缺陷特征:不同模块或文件间有类似或重复功能的类;不同类间有类似或重复功能的函数;同一父类的子类间存在相似或重复功能的代码。

  缺陷影响:代码膨胀混乱,不易维护,本来维护一处代码由于重复代码要维护多处。

  解决方法:提炼重复代码。如工具函数封装成工具类,通用功能封装成公共库。

  8、不稳定依赖(Unstable Dependencies)

  缺陷特征:一个子系统或模块依赖于另一个比它更不稳定的子系统或模块,如上层模块依赖于不稳定的底层模块,上层模块肯定会问题不断。

  缺陷影响:不独立,不稳定,牵一发而动全身。

  解决方法:当有依赖关系时,一定要先保证被依赖子系统或模块的稳定性。至少应保证不稳定的子系统要依赖稳定的子系统。

  9、未利用的接口(Underutiliaed Interface)

  缺陷特征:设计并实现了很多接口,大部分未使用或只在内部使用;定义了很多全局变量,大部分其它模块未使用。

  缺陷影响:冗余,设计过度,暴露可视化。

  解决方法:按需设计接口,不需要对外公开的变量和函数应该私有化。

 10、紊乱类(Schizophrenic Class)

  缺陷特征:一个类实现了多个不同的功能,如界面类又处理了业务相关的功能。

  缺陷影响:不易理解,耦合度高,公共方法太多。

  解决方法:对多个功能进行拆分。

  11、复杂类(Blob Class)

  缺陷特征:规模非常庞大、复杂性高的类,常常包含多个复杂函数,有多重功能。

  缺陷影响:圈复杂度高,内聚性差,耦合度高,不易看懂和维护。

  解决方法:解决复杂函数,结构要清晰,类功能应该单一。建议值:类行数应在2000以内。

  12、全能类(God Class)

  缺陷特征:一个类集中了多个不相关类的功能;一个类操作其它模块数据太多;大而复杂。

  缺陷影响:破坏了类的封装性,耦合度高,内聚性差,不易维护。

  解决方法:多个功能不相关的类应该分别封装成不同的类,适当搬移函数,解决复杂函数问题。

  13、歪曲层次(Distorted Hierarchy)

  缺陷特征:类的继承关系比较深。

  缺陷影响:复杂度高,不易维护。

  解决方法:类的继承层次结构不应该超过6。

  14、数据类(Data Class)

  缺陷特征:提供许多公共属性和函数,供很多其它类来操作,自己却很少操作。

  缺陷影响:非面向对象,缺乏封装性,不易维护。

  解决方法:封装性。

  15、破坏继承(Tradition Breaker)

  缺陷特征:派生类几乎没有使用任何继承父类的功能,却增加了全新的功能。

  缺陷影响:非继承关系却继承,难理解,不易维护。

  解决方法:理清类与类之间的继承关系,不适合继承关系的类应该单独分开。

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-10-25 21:52:12

多个常见代码设计缺陷的相关文章

央视曝三星手机存设计缺陷 维修漫天要价

[三星Note.S系列存重大设计缺陷:一天死机三十次]从"突然死机"到"无法开机"再到高价维修,已经成为众多三星手机NOTE系列及S系列机主的共同烦恼.<经济半小时>记者采访专家指出:这是因为,三星产品设计本身存在缺陷,很可能是存储芯片的擦除指令存在着问题,这个存储芯片相当于电脑硬盘.而就是这样的硬件设计问题,却让消费者买单,一次维修少则800块,多则2000块-- 智能机频频变"砖头"原因成谜,维修漫天要价消费者叫苦不迭 2012年

央视曝光三星手机存设计缺陷 修1次可高达2000元

三星手机存设计缺陷 维修漫天要价欺瞒消费者[三星Note.S系列存重大设计缺陷:一天死机三十次]从"突然死机"到"无法开机"再到高价维修,已经成为众多三星手机NOTE系列及S系列机主的共同烦恼.<经济半小时>记者采访专家指出:这是因为,三星产品设计本身存在缺陷,很可能是存储芯片的擦除指令存在着问题,这个存储芯片相当于电脑硬盘.而就是这样的硬件设计问题,却让消费者买单,一次维修少则800块,多则2000块--智能机频频变"砖头"原因成谜

Javascript的10个设计缺陷

前几篇文章,我经常说Javascript的设计不够严谨,有很多失误. 今天的这一篇,前半部分就谈为什么会这样,后半部分将列举Javascript的10个设计缺陷. 我参考的文献主要是Douglas Crockford的专著<Javascript语言精粹>(JavaScript: The Good Parts)和Fredrik Holmström的文章<我对Javascript的抱怨>(My gripes with Javascript). 一.为什么Javascript有设计缺陷?

改善代码设计 简化条件表达式(Simplifying Conditional Expressions)

系列博客 1. 改善代码设计 -- 优化函数的构成(Composing Methods) 2. 改善代码设计 -- 优化物件之间的特性(Moving Features Between Objects) 3. 改善代码设计 -- 组织好你的数据(Composing Data) 4. 改善代码设计 -- 简化条件表达式(Simplifying Conditional Expressions) 5. 改善代码设计 -- 简化函数调用(Making Method Calls Simpler) 6. 改善

改善代码设计 组织好你的数据(Composing Data)

系列博客 1. 改善代码设计 -- 优化函数的构成(Composing Methods) 2. 改善代码设计 -- 优化物件之间的特性(Moving Features Between Objects) 3. 改善代码设计 -- 组织好你的数据(Composing Data) 4. 改善代码设计 -- 简化条件表达式(Simplifying Conditional Expressions) 5. 改善代码设计 -- 简化函数调用(Making Method Calls Simpler) 6. 改善

戴尔笔记本电脑频现热得烫手被质疑存设计缺陷

[导读]刚买的戴尔笔记本电脑频频热得烫手,消费者怀疑电脑存在设计缺陷,要求换机遭到拒绝.<天天315>今天聚焦:"高烧不退"的戴尔笔记本电脑.近日,30多名消费者联名投诉:新买的戴尔[微博]笔记本电脑频现质量问题,尤其显卡高烧不退让人担忧.戴尔方面表示,显卡持续发热是正常现象,因为并没有出现自动关机或断电等问题.消费者对戴尔方面的回复极为不满,他们认为显卡过热是戴尔灵越14寸(5420)系列笔记本电脑普遍存在的问题,有可能是设计缺陷,联名投诉只为戴尔公司能够正视问题,然后对

改善代码设计 —— 组织好你的数据(Composing Data)

系列博客       1. 改善代码设计 -- 优化函数的构成(Composing Methods)       2. 改善代码设计 -- 优化物件之间的特性(Moving Features Between Objects)       3. 改善代码设计 -- 组织好你的数据(Composing Data)       4. 改善代码设计 -- 简化条件表达式(Simplifying Conditional Expressions)       5. 改善代码设计 -- 简化函数调用(Maki

改善代码设计 —— 组织好你的“.NET技术”数据(Composing Data)

系列博客       1. 改善代码设计 -- 优化函数的构成(Composing Methods)       2. 改善代码设计 -- 优化物件之间的特性(Moving Features Between Objects)       3. 改善代码设计 -- 组织好你的数据(Composing Data)       4. 改善代码设计 -- 简化条件表达式(Simplifying Conditional Expressions)       5. 改善代码设计 -- 简化函数调用(Maki

改善代码设计 —— 组织好你的数“.NET研究”据(Composing Data)

系列博客       1. 改善代码设计 -- 优化函数的构成(Composing Methods)       2. 改善代码设计 -- 优化物件之间的特性(Moving Features Between Objects)       3. 改善代码设计 -- 组织好你的数据(Composing Data)       4. 改善代码设计 -- 简化条件表达式(Simplifying Conditional Expressions)       5. 改善代码设计 -- 简化函数调用(Maki