一、基于度量的程序结构分析
首先给出Complexity metrics中参数的含义:
ev(G):基本复杂度是用来衡量程序非结构化程度的,非结构成分降低了程序的质量,增加了代码的维护难度,使程序难于理解。因此,基本复杂度高意味着非结构化程度高,难以模块化和维护。
Iv(G):模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。软件模块设计复杂度高意味模块耦合度高,这将导致模块难于隔离、维护和复用。模块设计复杂度是从模块流程图中移去那些不包含调用子模块的判定和循环结构后得出的圈复杂度,因此模块设计复杂度不能大于圈复杂度,通常是远小于圈复杂度。
v(G):圈复杂度是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数,即合理的预防错误所需测试的最少路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护,经验表明,程序的可能错误和高的圈复杂度有着很大关系。
第一次作业(包含幂函数的简单表达式求导)
第一次作业对面向对象的了解很浅,故而将读入的字符串全部放到一个DifferPoly类里面处理,包括了判断合法性,提取系数和指数,求导,合并同类项,输出这一系列过程。
由复杂度分析可以看出总体复杂度不高,其中output()和polylist()的模块设计复杂度高,说明耦合度高,在后面的作业中难以复用。
第二次作业(包括三角函数的简单表达式求导)
第二次作业分出了字符串类,单项式类和读入类,但是没有分三角函数类和多项式类,可以重构改进。
由复杂度分析可以看出有几个方法的基本复杂度高,应该降低其复杂度,提高结构性。output()方法对求导结果进行了化简输出,可以考虑化简和输出分开进行。
第三次作业 (包含函数嵌套的复杂表达式求导)
第三次作业是前两次的升级版, 需要比较好的对类的设计。我的程序分为读入类、字符串类、项类、多项式类、单项式类和嵌套项类,其中多项式、单项式和嵌套项都从项类中继承而来,使结构更加清楚。
递归求导的过程在对象与对象之间的转换过程中得以实现,让复杂问题简单化。缺点是每次求导直接返回结果字符串,没有很好的化简办法;判断合法性在字符串类中进行,应该在重构时考虑将判断这一过程同样交给其他类完成。
由复杂度分析可以看出Wholestr()类整体复杂度高,如上文所说,判断合法性全部在Wholestr()中进行,过于冗长,基本复杂度高,重构应重点修改。
二、程序bug分析
在三次作业中,第二次在强测中被测出bug:输出时为了优化“1*x”,replace“1*”时只考虑了1前面不能为数字,没有考虑“1”前面是“^”的情况。其余两次作业没有在强测和互测中被发现bug。
规避bug的策略:首先,TDD是非常重要的策略,在动手编程之前,应该认真阅读指导书,了解清楚要求,比如这三次作业的WRONG FORMAT问题,我在互测中发现很多同学出现bug都是因为对指导书中描述的什么是合法格式的输入不是很清楚,这也是很致命的问题;其次,在编程过程中,每写完一个部分都应该进行针对性的测试,这样可以有效避免bug累积,避免debug火葬场;最后,自己写完程序要自己进行测试,从格式问题到功能实现,各个方面检测,不要依赖测评机,自己测试的能力很重要。
三、发现别人bug采用的策略
主要采用黑盒测试,分类构造比较容易出错的测试样例,如,对于格式问题,构造非法字符,空白字符出现错误,不符合要求的函数格式,正负号数量问题等测试样例,对于合法情况的功能测试也应该由简单到复杂开展测试。其中前两次比较重视格式错误情况,第三次主要注重求导功能的测试。当发现了他人的bug时应对产生bug的原因进行一定的判断,避免构造同质测试样例。
在测试的时候写了比较简单的批处理脚本,批量产生运行结果,比较方便。
四、总结
第一单元主要认识了面向对象的基本思想,并解决了一类具体问题,但是过程中也不可避免地采用过以前面向过程编程的思路。应该多加练习,在实战中对面向对象程序设计加深理解。同时,优化方面的问题也值得继续探索。
希望继续加油鸭!
原文地址:https://www.cnblogs.com/peggyhss/p/10604734.html