BUAA OO第一单元总结

21371110-戴波 学生 2023-03-19 01:02:30

第一次作业


        要求: 通过对表达式结构进行建模,完成多变量多项式的括号展开,初步体会层次化设计的思想。

架构

        这是代码量:

       这是总的代码:

 类图:

函数分析:

 

 


分析

          由于是第一次写面对对象程序,所以在第一次练习的基础上实现了这个架构,可以看到写的很臃肿而且结构十分混乱。

          第一次作业只要求我们解析一层括号,如果使用递归下降的解析方法的话,是可以直接解析多层括号的,我们要对一个表达式进行分析,面对对象要求我们从数据和行为上进行分析,现在来看,数据层面可以分为 表达式,项,因子,其中 表达式由若干项组成,而因子又分为常数因子和幂函数因子,从行为进行分析的话则有加法,减法,乘法,阶乘等,总的来说就是同类项合并。

         面对对象程序主要包括数据对象类,对象管理类和主控类,在第一次作业中我们的主控类就是MainClass。

          从类图中可以看到数据对象类Factor,Term和Expression都继承了Element类,但是由于不好的设计,导致基类其实可有可无,并且没有细致的行为和数据层次的划分,所以有很多类似的方法,如Simplify方法和Synthesis方法,三个数据类都应该又有乘法,加法的合并功能,在第一次作业这中,我使用重写方法居多,这主要是由于对面对对象的不熟悉。

         对象管理类有Lexer类和Parser类,及语法分析类和语义分析类,Lexer根据我们设定的语义来进行提取元素,然后Parser类读取Lexer读取到的元素,来判断是否是表达式,或是项,或是因子,最后进行合并,Lexer需要对输入的字符串进行预处理,即删除其中的空白字符,将阶乘符号** 转化为^,Paser读取元素时需要读取符号,如加号减号等,Paser首先调用PaserExpression,然后调用PaserTerm,最后调用PaserFactor,

         在第一次作业中,我使用正则表达式的方法来判别细小元素的差别,这种使用导致了第二次作业的错误。

        程序的输入为单纯的输入字符串,而输出我才用上层调用下层的方法,实现最底层的Factor toString函数,从度量分析中可以看到,toString的复杂度相对比其他方法要高很多,这是因为在处理时进行了简单的优化使用了嵌套的判断和循环语句导致的,然后上层的toString只需要调用下层就好了,这种思想在后面的作业中越来越重要,将使用的底层方法看作为黑盒,尽可能地减少输入地相关参数,这应该是老师说的提高内聚性,降低耦合度,这种思想方便我们进行迭代和修改功能,在未来的工作中需要这种方法。


出现的错误

       在多项式合并的时候,使用了之前使用过了的项,然后就是在优化结果的过程中,误将0从结果中删去,这些错误基本都出现在复杂度高的方法中,融合在混乱的代码中难以找到,所以需要尽可能地降低方法地复杂度来减少错误。


第二次作业

       要求:在第一次作业的基础上,加入了多层括号以及三角函数和自定义函数。

度量分析

      这是代码量:

    这是总的代码:

       这是类图:

 这是度量分析:

 


度量分析

          第二次作业相比第一次作业多了Triangle(三角函数)类和Function(类),同时将 常数 * 若干变量 * 若干三角函数作为第二次作业中总的最小单位Factor,Expreesion包含了若干个Factor,他们都继承自Item,但是由于设计的还是不好,所以并没有发挥太大的作用,只发挥了统一参数入口的作用,其中Function类统一管理输入的自定义函数并化简,Lexer和Parser类还是保持和上次作业一样的功能。

        和第一次作业相比,在行为层次上增加了求导这一方法,对表达式求导通过逐级调用求导方法的方式解决,即上层derive方法调用下层derive方法。

        这次作业和上次作业相比,使用了Hashmap,因为对Java的容器并不熟悉所以不能熟练运用,导致处理数据处理的不够好,Hashmap主要方便用来合并同类相,但是需要重载hashcode方法和equal方法,但是Factor级的判定同类相和他包含的Constant,Variable以及Triangle的判定方法又不相同,这种模糊的设计导致了第二次作业中出现了重大错误。

        受第一次作业的影响,采用模块化的设计思维,但是由于设计不当导致过于模块化,代码写的臃肿复杂,可以从代码量分析中看到甚至比第一次作业还多,当然这样的好处是构思快,写起来快。第二次作业我并没有花很多时间就写完了,但是并没有测试导致强测出现了错误。


错误分析

        有个犯的错误十分离谱,因为合并的时候有层循环忘记删掉了导致合并结果出错,然后还有一个错误就是正则表达式求元素出错导致RE,正则表达式的写法十分重要,在使用前应该经过反复测试才行,这些错误都是不应该犯的错误,在这里我意识到了正确地测试地重要性。


代码测试

        我们可以根据输入地元素地种类来构造测试数据,如常数,指数,三角函数,自定义函数以及表达式的各种组合,同时在写代码时的时候就应该留心哪些地方是容易出错的,应该重点考察那些地方,通过提升程序的健壮性,减少犯错的可能。


第三次作业

       要求:在第二次作业的基础上,新增了求导算子,以及自定义函数递归调用

度量分析

     这是代码量:

 

    这是类图:

 

 这是方法分析:

 


第三次作业总结

     在前两次的基础上,总算好好运用了面对对象的一点知识,在本次作业中使用了接口Factor,符合面向接口的编程思想,然后Variable,Triangle都补充自该接口,最小单位Term包含了一个常数,若干个Variable和Triangle,总结了第二次作业犯下的过度模块化问题,然后使用继承和多态来进行代码的编写,从数据层次上来说有Expression和Term,Term中包含了Variable和Triangle,这里与前两次作业类似,Function由于采用了递归调用其他函数,所以需要在输入完函数时对函数进行PaserExpression得到函数的最简单表达式。Lexer和Parser类还是保持和前两次作业一样的功能。

    第三次作业写起来是比较轻松的,甚至代码量比前两次作业还要少一些,说的上是一种进步?并且没有犯错,终于实现了hack数为0,自己也懒得去hack其他人,第三次作业是在第二次作业的基础上进行了重构了的,还好代码量少,不需要花太多时间。


第一单元的总结

      可以说最开始的第一次是最难的,需要使用之前没有使用过的递归下降方法以及Java等,但是结合老师上课讲授的知识后变得不那么难,面对对象大致有封装,继承,多态等,使用抽象的概念,来创建类和对象,我们可以从数据层次和行为层次来进行抽象设计,另外,好的架构是十分必要的,设计是永远大于实现的,在设计好功能之后,实现是相对简单的。我的代码水平总算上升了那么点,工程能力也得到了提高,算是oo的收获之一吧。


关于重构

    后面两次作业都是重构了的,因为自己的代码写的实在是不堪入目,所以只好重构,重构的过程中可以重新思考设计的正确性,方便我们添加功能,但是在以后的工作中,大规模的重构是近乎不可能的,所以我们需要好的架构和设计,来保证迭代的可持续性。


关于测试

       测试是写程序必不可少的一部分,我们需要尽可能地在写程序时就想好出现错误的可能性并规避错误,另外在测试时,要尽量减少同质错误的测试,提高测试的覆盖性,可以使用自动化工具来进行测试节约时间等,这是我第一单元得出的教训。

...全文
25 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

444

社区成员

发帖
与我相关
我的任务
社区描述
2023年北京航空航天大学《面向对象设计与构造》课程博客
java 高校 北京·海淀区
社区管理员
  • 被Taylor淹没的一条鱼
  • 0逝者如斯夫0
  • Mr.Lin30
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧