oo第一次总结

时间:2022-07-12 17:24:20

基于度量来分析程序结构

借鉴其它博客,利用IntelliJ自带Diagrams和MetricsReloaded插件来分析程序结构

主要的量度有以下三种,

ev(G):即Essentail Complexity,用来表示一个方法的结构化程度,范围在$[1,v(G)]$之间,值越大则程序的结构越“病态”,其计算过程和图的“缩点”有关。

iv(G):即Design Complexity,用来表示一个方法和他所调用的其他方法的紧密程度,范围也在$[1,v(G)]$之间,值越大联系越紧密。

v(G):即循环复杂度,可以理解为穷尽程序流程每一条路径所需要的试验次数。

第一次作业

 oo第一次总结

第一次作业结构比较简单和清晰。

 oo第一次总结

大多数方法处于一个比较合理的状态,Poly.outPoly()方法iv(G)和v(G)值比较高,此方法的作用是输出多项式,因为需要处理特殊的系数和指数情况,所以分支比较多。可以考虑输出优化单独做一个类。这次作业输入处理上利用正则表达式进行匹配,用的是一个大的正则表达式来匹配。这样导致的问题是编写比较困难,而且结构不够清晰,错误率高。多项式合并是先对每一项进行排序,然后在进行合并,其他地方就每什么需要特殊说明的了。

 

第二次作业

 oo第一次总结

沿用第一次作业的结构,在Term类中添加sin和cos的指数属性。

 oo第一次总结

除开与第一次作业相同的异常值外,Term的构造函数和多项式优化的复杂度比较高。这次的作业将每一项的分析放入了Term的构造函数中,所以复杂度比较高,可以将此部分划归到输入处理类。而多项式的优化需要考虑到合并转化等问题,复杂度高也有其合理性。这一次的正则表达式的构造采用分层的结构,编写难度和编写正确性上都得到了提升,但是还有一个细节上的问题,在处理\t和空格时,放在了正则表达式上去处理。这样导致正则表达式还是有一些臃肿,可以采用先匹配\t和空格所导致的错误,然后去掉\t和空格。优化上只做了一些简单的优化,利用hashmap进行同类项合并。

 

第三次作业

 oo第一次总结

与一二次作业相比,更加细化了结构。Poly、Term、Factor三重结构更加清晰,也易于管理。

 oo第一次总结

Lex.getNext()作为词法分析的核心部分,其需要判断单词类型,所以v(G)比较高。同第二次作业的问题,构造函数需要处理输入,复杂度高。标准的正则表达式不具备处理递归的情况,所以这次实现语法分析来处理输入,这次公测的bug也来自于这里。这次对于不同的Factor采用继承的方式,并且实现了求导接口。由于对继承的不熟悉,导致实现起来有很多不合理的地方。最主要的就是访问控制相关问题。子类不能访问父类的私有变量。需要父类实现get和set方法。

 

程序的bug

第一次作业 内容比较简单。但是对于\v这种空白字符没有进行处理。

第二次作业 在输入的处理上还是出现的错误,对于没有任何输入的情况没有进行处理,这个不够在第一次作业中同样存在。

 oo第一次总结

第三次作业 语法分析中分析因子部分,缺少else分支,即判断输入错误的分支。能够识别正确输入,但某些错误输入会导致程序崩溃。

 oo第一次总结

由于我们没有互测模块,就写一些自己测试的方法。就整体测试而言,主要依靠自己编写的测试样例。错误样例主要是通过自己的理解和与同学的讨论得出的。正确样例就是按指导书进行编写,尽可能覆盖每种情况,依靠matlab的工具验证结果的正确性。当然手工编写的效率不高,测试力度小,测试分支覆盖不完善,后期还是需要结合一些自动化的测试。在每完成一部分后,会编写测试样例对固定模块进行测试,保证单一模块的正确性后,再进行整体的测试,这样发现bug的效率会相对较高。

 

Applying Creational Pattern

 

单例模式(Singleton Pattern)

整个词法分析以及语法分析只会用到一次,可以保证一个类仅有一个实例,并提供一个访问它的全局访问点。

工厂模式(Factory Pattern)

对每一种函数建立类,对每一种组合规则建立类。实现各种的工厂,使得具体的产品对象中被解耦。

 

总结

经过这几次作业的连续,了解了以对象为基础的编程方式,但是在选择对象上还是有很多不够了解的地方。最开始实现的类,都是实体类(数据管理类),没有把输入数据处理作为一个类,这导致类过于复杂。

还有就是对于继承和接口的应用不恰当,这使得类关系比较混乱,而且因为对继承父类子类关系的不够了解,在实现过程中出现了相当多的强制类型转化,这是不应该出现或者滥用的。