OO第一单元总结

第一单元总结

一、架构分析

1.第一次作业

(1)类图

(2)架构思路

本次作业架构较为简单,用一个数组构成的Num即可存储所有可能出现的数据(即用数组的偏移量映射x的指数,数组元素为对应系数),FactorClass、TermClass、ExprClass采用递归下降的方法(ExprClass分解为TermClass加或减ExprClass,TermClass分解为FactorClass乘TermClass,对于最底层的FactorClass则使用正则表达式对每种因子进行解析)将字符串解析为Num类,五种计算方式类以Num类作为输入和输出的数据类型。

(3)度量分析

 

 

2.第二次作业

本次作业除三角函数类的属性设置外,其余内容与第三次作业并无较大差别。本次作业的三角函数类由sin:boolean(函数类型是sin则为true,是cos则为false),digit:boolean(括号内是常数则为true,是变量则为false),value:BigInteger(digit==true则value代表常数的值,digit==false则value代表x的指数),index:BigInteger(三角函数的指数)。其他内容详见第三次作业部分的描述。

3.第三次作业

(1)类图

(2)架构分析

1) 数据结构

本次作业中所有计算的输入输出数据类型都为ExprClass类,即ExprClass作为本次作业的数据存储结构。ExprClass类包含TermClass的容器TermClasses,项容器中的每一项相加构成这个表达式对象;TermClass类包含系数(coefficient)、x的指数(index)、三角函数容器(triAngles),这个项对象可在数学上映射为coefficient*x^index*triAngles;triAngle类包含三角函数名(sin)、指数(index)、括号内的表达式(content),这个三角函数对象可在数学上映射为[sin(sin==true)|cos(sin==false)](content)^index。

2) 解析过程

本次作业除了数据存储结构更改外,在不涉及自定义函数和求和函数的字符串解析中仍延续了homework1的递归下降思路(详见一、1.(2))。当factor函数遇到自定义函数和求和函数时,不再由自己处理,而是将这个字符串整体传给sum和func方法,再返回这两个方法返回的ExprClass类数据。

对于求和函数sum,使用正则表达式解析出起始和终止的i值,以及求和表达式,在对求和表达式中的i进行替换后,直接交由expr方法处理,得到返回的ExprClass类数据。

对于自定义函数func,在主函数输入自定义函数时使用正则表达式解析函数名(name)、形参(parameter)、函数表达式(expression),并将这个自定义函数对象添加到自定义函数容器functions中。当factor方法调用func方法时,先用正则表达式解析出函数名、实参,用函数名与functions中的函数匹配,再将形参替换为实参,把得到的表达式交由expr方法处理,得到返回的ExprClass数据。

3) 化简思路

本次作业创建了termSimplify和exprSimplify方法对项和表达式进行化简。

对于项的化简,只需化简项的三角函数,即对三角函数容器triAngles进行处理:当遇到值为1的三角函数因子时(cos(0)或index==0),直接去掉该项即可;再进行同类项合并,从容器的最后一项向前遍历,对于每一项obj1,判断在其之前的项obj2是否有相同的三角函数名(sin)和括号内表达式(content),若有,则将obj1删去,将的指数(index)加到obj2的index上。

对于表达式的化简,分为三步:

i)进行与项的化简类似的同类项合并操作,不同的是,对于同类项的处理不再是index相加而是coefficient相加;

ii)对所有项进行二重遍历,若有两项有两个三角函数因子不同名且content相同且index均为2,且这两项除这个三角函数因子外的所有属性都相同时,可进行三角函数平方和为1的化简,即删去其中一项,并将另一项的该三角函数因子删去。

iii)删去表达式中所有值为0的项(调用isZero方法以判断该项是否为0,iszero方法的功能是判断项的系数是否为0、是否有等于0的三角函数,满足任意一项即返回true)。

(3)度量分析

 

 

二、质量分析

1、bug分析

本单元被发现的bug全部集中在toString函数中,第一次作业由于对系数为-1的项输出特判却未将”-1“输出特判,导致”-1“被错误输出为”-“;第三次作业由于对指导书的描述未彻底理解,误以为三角函数中系数为-1的因子不需要双重括号。

出现bug的第一次作业中Num.toString函数和第三次作业中TermClass.toString的行数、圈复杂度、认知复杂度都很高。由此可见,高复杂度的方法极易因疏忽而产生bug。因此在以后的学习中,要尽量让代码保持简明清爽的特点,以减少bug的产生。

2、debug策略

本单元主要根据指导书中的形式化表述构造测试数据,对于容易出错的结构和化简、输出方法中易疏漏的数据进行测试。

3、架构质量分析

根据度量分析中的数据,本单元的代码复杂度平均较高,且并未很好地进行高内聚、低耦合的设计,需要在以后的学习中加以改进。

三、心得体会

1.总述

在本单元的学习中,我初步建立了对面向对象程序的认识,认识了对象的结构特征,理解和掌握了层次化设计,逐步进行了从面向过程到面向对象的设计思路的转变。

2.pre课程

在学习的过程中,我认识到了pre课程的重要意义,在正式课程的许多方面都需要用到在pre中学到的知识,如类的创建与管理、正则表达式的使用、类图的设计方法等。

3.代码风格

此外,由于课程组对代码风格的硬性规定,我对代码风格也有了新的认识,好的代码风格不仅能增强代码的可读性,也能有效减少bug的产生。

4.测试

在本单元的学习中,我对测试的方法和重要性有了更有建设性的见解。同时也认识到了测试并不能发现所有的bug,我们仍要从产生bug的源头做好工作,以减少bug的产生。

5.功能与性能的辩证思考

程序的最重要的是完成它本身的功能,而更好的性能则是锦上添花。当我们对程序性能进行优化时,一定要兼顾其功能的正确性,这是从本单元的bug中得出的深刻教训:为了提升少许性能,却因考虑的疏忽导致了部分用例的功能错误,最终得不偿失。

虽然每次的作业不可能达到完美,但我们至少在为了达到完美而不懈努力。这也正如我们的人生:一个人重要的不是所处的位置,而是他所朝的方向。

posted @ 2022-03-26 13:54  Rupertail  阅读(15)  评论(1编辑  收藏  举报