多个常见代码设计缺陷有哪些,多个常见代码设计缺陷怎么写
在软件设计和开发中,代码设计体现在子系统、模块和模块以及功能之间的关系。软件设计越差,维护成本越高,质量往往难以达标和好评。
好的设计必须是:层次关系简洁、清晰,易于维护和扩展。
我不会研究太高级的设计,只总结一些常见的代码设计缺陷。如果这些设计缺陷能够得到很好的解决和避免,相信代码能力(编写、设计、评审、重构)能够提升到一个更高的层次。
本文主要介绍以下15种常见的代码设计缺陷:
缺陷:指代码多行、分支嵌套深、变量多、参数多、注释多、复杂度高的函数。
缺点:功能不易理解和维护,代码重复冗余。
解决方案:当开发新代码时,功能变得越来越复杂。我们要有意识地、主动地把它们分解、细化成小功能或具有独立功能的功能。甚至当我们觉得需要用注释来解释某个东西的时候,其实也应该成为一个独立的功能。函数建议值:代码行24,if嵌套深度6,圈复杂度10,函数应该是single。
缺陷:函数参数多,参数表相似,重复调用同一个参数表。
缺陷:大量重复,影响编译效率;参数,很难理解和调用。
解决方案:参数列表应该封装到一个结构中。建议:函数参数平均为2,避免超过5。
伪代码示例:getdate (int year,int month,int day,int time)-getdate(struct date range)。
缺陷:它包含一个头文件,但是头文件中没有任何东西被使用。
缺点:编译链接速度慢,耦合度高,错误包含头文件。例如,如果包含了头文件,但没有使用其中的内容,并且头文件依赖于dll,则会导致不必要的dll依赖和错误。
解决方法:头文件不能随机包含。100%确认每个包含的头文件的使用情况,删除不必要的头文件。
缺陷:一个函数调用了其他模块的大量函数,却调用了本模块的少数函数。
缺陷:一个函数与多个函数关系过于密切(这些函数属于一个或两个类);一个类为一个外部函数调用提供了许多函数;耦合度高,类不够抽象。
解决方案:明确内部和外部模块的功能,外部模块要调用的足够抽象。
缺陷:多个子系统是一个循环的相互依赖关系;函数的调用关系是混沌循环的;文件的直接或间接交叉引用。
缺点:难以理解和维护,编译速度慢,关系混乱,难以重用。
解决方案:多文件或系统要明确划分结构和层次关系,并且要无环。
伪代码示例:循环包含头文件,文件A包含文件B,文件B包含文件A.
缺陷:函数很少访问自己的模块数据,总是访问外部的模块数据;较少访问自己的模块,较多访问其他模块;和数据操作不在同一个模块中;我对其他种类的数据感兴趣。
缺陷:高耦合。
解决方案:同一个模块的数据和操作要放在一起。
特点:不同模块或文件之间功能相似或重复的类;不同类之间函数相似或重复的函数;同一父类的子类之间具有相似或重复功能的代码。
缺陷:代码臃肿混乱,不易维护。原来维护的一个代码,由于代码重复,不得不在很多地方维护。
解决方案:细化重复代码。比如工具函数封装成工具类,通用函数封装成通用库。
缺陷:一个子系统或模块依赖于另一个比它更不稳定的子系统或模块。比如上层模块依赖不稳定的下层模块,上层模块肯定会有问题。
缺陷:不独立,不稳定,影响全身。
解决方案:当存在依赖关系时,首先要保证依赖的子系统或模块的稳定性。至少要保证不稳定子系统依赖于稳定子系统。
特点:设计实现了很多接口,大部分没有使用或者只在内部使用;定义了很多全局变量,其他大部分模块都没有用到。
缺陷:冗余,过度设计,曝光可视化。
解决方案:按需设计界面。不需要公开的变量和函数应该私有化。
特性:一个类实现许多不同的功能,比如接口类也处理与业务相关的功能。
缺点:不容易理解,耦合度高,公共方法太多。
解决方法:拆分多个功能。
缺陷:规模非常大,复杂程度非常高的一类,往往包含多个复杂函数,具有多种功能。
缺点:复杂度高,内聚性差,耦合度高,难以理解和维护。
解决方法:解决复杂函数,结构要清晰,类函数要单一。建议:类行数应在2000以内。
缺陷:一个类集中了几个不相关类的功能;一个类的数据太多,无法操作其他模块;又大又复杂。
影响:破坏了类的封装性,耦合度高,内聚性差,维护困难。
解决方法:将多个函数不相关的类打包到不同的类中,适当移动函数,解决函数复杂的问题。
缺陷:提供了很多公共属性和函数给很多其他类操作,自己很少操作。
缺点:非面向对象,缺乏封装,维护困难。
解决方案:封装。
缺陷:派生类几乎没有使用任何继承父类的函数,而是添加了全新的函数。
缺陷:非继承关系是继承的,难以理解,难以维持。
解决方法:理清类之间的继承关系。不适合继承关系的类要分开。