您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 好圈复杂度概念重构方法及案例分析潘洪亮2015-12-03
扬帆起航圈复杂度CyclomaticComplexityis17(maxallowedis7).CyclomaticComplexityisX(maxallowedisX)hongliangpan@gmail.com我的QQ:28797575知道做什么吗?文档示例•无目录•有目录不聚焦不知道目标,不知道总体结构不知道是否合理没有层次是否有遗漏带来时间成本质量问题4知道做什么吗?hongliangpan@gmail.comQQ:28797575圈复杂度概念概念计算方法检查工具二不二重构方法案例分析McCabe复杂度圈复杂度基本复杂度模块设计复杂度设计复杂度集成复杂度行数全局数据复杂度局部数据复杂度病态数据复杂度规范化复杂度框架群:181124238我的QQ:307087558(1)圈复杂度(CyclomaticComplexity(v(G)))概念圈复杂度是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数。计算方法如果一个模块流程图有e条边n个节点,它的圈复杂度v(G)=e-n+2。hongliangpan@gmail.comQQ:28797575•圈复杂度(CyclomaticComplexity)是一种代码复杂度的衡量标准。它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立线性路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难于测试和维护。程序的可能错误和高的圈复杂度有着很大关系。•圈复杂度主要与分支语句(if、else、switch、for等)的个数成正相关。当一段代码中含有较多的分支语句,其逻辑复杂程度就会增加。什么是圈复杂度hongliangpan@gmail.comQQ:28797575示例•下面这个实例中,单元测试的覆盖率可以达到100%,但是很容易发现这其中已经漏掉了一个NPE的测试用例。case1方法的圈复杂度为2,因此至少需要2个用例才能完全覆盖到其所有的可能情况。•//程序原代码,圈复杂度为2publicStringcase1(intnum){Stringstring=null;if(num==1){string=String;}returnstring.substring(0);}•//上面代码的单元测试代码publicvoidtestCase1(){Stringtest1=case1(1);}圈复杂度主要与分支语句(if、else、,switch等)的个数成正相关。当一段代码中含有较多的分支语句,其逻辑复杂程度就会增加。hongliangpan@gmail.comQQ:28797575hongliangpan@gmail.comQQ:28797575圈复杂度计算概念计算方法检查工具二不二重构方法案例分析hongliangpan@gmail.comQQ:28797575示例•如果一个模块流程如下有e条边n个节点,它的圈复杂度v(G)=e-n+2•例:hongliangpan@gmail.comQQ:28797575圈复杂度的计算•圈复杂度(cyclomaticcomplexity):M=E−N+2PE:边的数量N:节点的数量P:分离部分的数量,一般为1,都是联通的圈数(cyclomaticnumber):M=E−N+PE,N,P参数同上圈复杂度和圈数之间的关系为:对有向图A,将A的每个出口(exit)与相应的入口(entrance)相连得到有向图B,则A的圈复杂度与B的圈数相等圈复杂度又叫做CC复杂度,也可能被称为循环复杂度,它表达的是if..then..else..,swith..case..,循环语句等分支语句造成的程序控制流复杂程度hongliangpan@gmail.comQQ:28797575计算公式补充•通常使用的计算公式是V(G)=e–n+2,e代表在控制流图中的边的数量(对应代码中顺序结构的部分),n代表在控制流图中的节点数量,包括起点和终点(1、所有终点只计算一次,即便有多个return或者throw;2、节点对应代码中的分支语句)。hongliangpan@gmail.comQQ:28797575•例如下图示例一个单入口、单出口的程序图(不是结构化程序图),其圈复杂度为10-7+2=5:•从节点G到A添加一条有向边,则成为一个强连通有向图(该方法对其它结构化程序图同样适用),其圈数为11-7+1=5,与上图的圈复杂度相同:hongliangpan@gmail.comQQ:28797575计算示例publicStringcase2(intindex,Stringstring){StringreturnString=null;if(index0){thrownewIndexOutOfBoundsException(exception0);}if(index==1){if(string.length()2){returnstring;}returnString=returnString1;}elseif(index==2){if(string.length()5){returnstring;}returnString=returnString2;}else{thrownewIndexOutOfBoundsException(exception2);}returnreturnString;}hongliangpan@gmail.comQQ:28797575•根据公式V(G)=e–n+2=12–8+2=6。case2的圈复杂段为6。说明一下为什么n=8,虽然图上的真正节点有12个,但是其中有5个节点为throw、return,这样的节点为end节点,只能记做一个。计算示例检查工具概念计算检查工具二不二重构hongliangpan@gmail.comQQ:28797575检查工具•开发中常用的检测圈复杂度的工具,PMD,checkstyle都可以检测到高复杂度的代码块•EclipseMetric插件:有效地查出复杂度•JavaNCSS–NCSS表示NonCommentingSourceStatementshongliangpan@gmail.comQQ:28797575工具目的Eclipse插件的URLCheckStyle编码标准分析测试代码覆盖率复制/粘贴检验包依赖项分析复杂度监控±2原则概念计算方法检查工具二不二重构方法案例分析hongliangpan@gmail.comQQ:28797575直接管好几百人•女:有三室两厅吗?•男:没有•女:有路虎,奥迪吗?•男:没有!•女:有7位数存款吗(?•男:没有+!•女:那你有啥?•男:我………女转身就走,。•突然男的说:我管理几百人(。。。•女立刻回头抱住男的腰,满脸崇拜的说道:死鬼,你不早说,这就够了!!!那是什么公司高层?•男:我是群主群主烧锅炉翻样中国版主hongliangpan@gmail.comQQ:287975757±2原则•如果你二,你就关注7+2件及以上事情【二货九个圈】•如果你不二,你就关注7-2件及以下事情【不二五个圈】•圈复杂度高的,可以重构为•如:•1.参数判断•2.取数据•3.数据预处理•4.数据转换•5.返回数据••每一步可以是一个独立的方法•这样主干逻辑非常的清晰,也就不二金字塔原理:有目标、有层次、有顺序总分总结构把大象放冰箱里,统共分几步?hongliangpan@gmail.comQQ:28797575代码大全25知道做什么吗?系统开发流程开发流程工作内容总体设计迭代设计编码自测系统测试产品发布迭代测试产品规划需求目标迭代设计UIUE设计Flex系统架构设计编码测试用例编写【稳定需求】单元测试集成测试总体设计产品规划需求目标产品发布支持性文档编写系统测试αβ项目总结迭代评估迭代规划设计文档迭代规划文档测试用例需求细化(包括UI)需求细化包括UIUE单元测试编码代码审查集成测试迭代测试外部测试测试用例过程文档调整文档整理产品发布迭代设计文档调整用户测试经验总结迭代评估支持性文档编写26总共分5步评审、会议常见问题27如果去掉第二层圈复杂度是。。hongliangpan@gmail.comQQ:28797575写文档没有目录大纲模块设计:一个包下N多个类代码:超大方法超大类圈复杂度的重构控制圈复杂度的N种重构技术----Refactoring:ImprovingtheDesignofExistingCode概念计算方法检查工具二不二重构方法案例分析金字塔原理总分总结构把大象放冰箱里,统共分几步?金字塔原理写代码和写文章、画画总分总结构把大象放冰箱里,统共分几步?业务重构架构重构设计重构代码重构重复。代码重复、结构重复、逻辑重复。重复的代码是抽象不够的表现。如果是一个独立完整的概念,可以提取成一个子程序(抽象)。举例:多处的排序算法。冗长子程序。如果把子程序的一部分提取来作为另一个独立的子程序,可以让代码更清晰,就提取成子程序。循环过长或嵌套过深。循环内部的复杂代码往往可以转换成子程序。嵌套过深可以用前面“语句”中提过的方法解决。子程序命名不当。需要子程序重命名,或合并、拆分子程序。难懂、拙劣的代码。需要重整逻辑和流程。…代码重构降低圈复杂度的方法——重构概念重构(Refactoring)就是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。重构方法重复代码或者相似代码提取为一个新的方法将过长的方法按功能拆分成小的方法将过大类的功能拆分成多个功能单一的小类推荐书籍《重构——改善既有代码的设计》作者:MartinFowler书中列出了长达70条的重构名录,提供了具体重构的方法和重构的技巧。将帮助开发人员一次一小步地修改代码,减少了开发过程中的风险。hongliangpan@gmail.comQQ:28797575Page32可以直接降低圈复杂度的10种重构技术针对结构化编程:ComposingMethods(重新组织你的函数)1.ExtractMethod(提炼函数)2.SubstituteAlgorithm(替换你的算法)SimplifyingConditionalExpressions(简化条件表达式)3.DecomposeConditional(分解条件式)4.ConsolidateConditionalExpression(合并条件式)5.ConsolidateDuplicateConditionalFragments(合并重复的条件片断)6.RemoveControlFlag(移除控制标记)MakingMethodCallsSimpler(简化函数调用)7.SeparateQueryfromModifier(将查询函数和修改函数分离)8.ParameterizeMethod(令函数携带参数)9.ReplaceParameterwithExplicitMethods(以明确函数取代参数)---Refactoring:ImprovingtheDesignofExistingCode针对面向对象编程:10.ReplaceConditionalwithPolymorphism(以多态取代条件式)控制圈复杂度的10种重构技术总结可以直接降低圈复杂度的9种重构技术(针对结构化编程):*一、ComposingMethods(重新组织你的函数)1.ExtractMethod(提炼函数)分为不同的step步骤进行处
本文标题:好圈复杂度概念重构方法及案例分析潘洪亮2015-12-03
链接地址:https://www.777doc.com/doc-2518896 .html