oo第一次作业
前言:
这是一篇面向对象作业总结,作业内容是对多项式进行求导,一共有三个阶段,具体要求不详述,第一阶段只要求’+’连接coeff*x^pow的形式,第二次支持*连接的幂函数及三角函数,第三次则需要支持括号表达式的嵌套。本想不用编译原理所述表达式树,最后发现做成一团乱麻。
第一次作业
类图如下:
说明:第一次作业比较简易,主要是对新版eclipse和checkstyle的安装和熟悉。词法分析器为Token,可以考虑将其单例化,因为只有一个词法分析器。用Poly存储多项式的系数和幂次,在PolyDif里有着主入口,根据加号拆项,以HashMap<>存入<幂次,系数>,按求导法则进行求导,最终遍历Map以输出结果。
代码度量结果如下:
Bug:不能直接去除所有空格,因为+ 10不算数字。
0不输出,由于大整数0输出时前面没有+,导致我强测三处没过,改正方法就是判断系数是否为0,是则跳过。
还有其他,总的来说,bug存在于词法分析程序以及输出程序,因为其分支比较多。
第一次作业略述如上。
第二次作业
类图如下:
三个Minizer可以不用看,因为不支持括号表达式,所以提取公因式无效
第二次作业也没有什么优化,仅仅是系数合并。构造了一个CompTerm的类,表面一个项由系数、幂次、sin幂次、cos幂次所唯一决定,这种断言有局限性,不宜扩展,但是可以有效合并系数。
Bug: 由于多处抛出异常,所以导致最后异常没有处理,就是没有输出wrong format,但是打印函数堆栈。最终把所有异常都交给了主入口main。
度量结果如下:
这里有一个静态属性,但是不是词法分析程序,他是scanner。而词法分析器被分给了diff主控程序,就是语法分析器,这样造成的问题在第三次作业中有所体现。总之,这个类关系勉强可以应对现有需求。
第三次作业
第三次作业的类构造是有问题的,类图如下:
这个类关系图甚至比上一次还要少了,其中Diff本来是对表达式进行语法分析的一个类,它内嵌了一个词法分析器,还有两个字符串,一个是输入的表达式,一个是求导后的表达式。而对因子和项进行分析的函数调用了专门负责求导的函数。作为结果,对项和因子进行分析的两个函数getTerm和getFactor,都是用两个字符串作为返回值的,一个意味着分析到了什么样的串,一个是求导后的结果。然而我直接用Diff类本身作为其中方法getTerm和getFactor的返回值,让Diff类的功能比较模糊。Sin和cos又继承了Diff类,意味着创造它们的实例就可以得到Sin(…)和其求导结果。然而这样做使得词法分析器进行了复制和分裂,就不再是全局的词法分析器了,这样一方面占用额外内存,还会导致各个词法分析器处理到的位置是不同步的,这里有很多bug,而这样仅仅是让Sin可以独立分析其自身表达式。最后在优化时,由于Diff功能太过耦合,所以Optm不能再继承Diff,而是另外完成了一个语法分析器,代码多有类似。
问题的本质就是不想用全局变量,可以说所有类的实例都是临时开的,然后通过字符串进行互相传递,没有抽象出表达式树。可以开两个静态变量,就是词法分析器和表达式树的根节点,而不是完全依赖与语言递归的特性进行字符串处理。
度量结果如下:
可以看出,代码规模并不比第二次大多少,这是因为删了第二次中的许多额外功能。
圈复杂度还是过高,3.171,就是分支数太多,这不oo,按照树的方式重构,然后节点实现统一的接口,也许可以降圈复杂度。方法数有72个,这是因为里面大量的都是get和set方法,不能有protected就只能这样进行同步。静态方法还可以再减少,因为那3个方法只是给main用的。Static方法不是不能用,单例模式就要用,但是也不能专门造一个类把所有的方法都设置成static的了,这是底线。想尽量减少static,就发现所有容器都是函数里的临时变量。Static还是要适中。
Bug: 由于用的是字符串进行传递,所以老是会出现括号存去问题。对于(++sin(x))这样的,去括号后是++sin(x),逐层求导后发现是++cos(x),返回时又要去括号,则会出现…*++cos(x)这样的错误串。解决方案是写了个while去掉前导符号。
还有一些bug诸如词法分析器同步时尾部空格数不一样导致偏移值不同,这种bug太细节了,就不多赘述了。
这些bug产生的规律都是由于字符串没有抽象成语法树所造成的。
设计模式
可以考虑工厂模式,因为每次创造Diff或Sin或Cos或Poly或Optm的时候,都只是为其词法分析器赋值,没有牵涉到求导的情况。又不好把求导直接写进构造器,所以可以用工厂方法,制造一个工厂,产生实例的同时执行其特征操作。工厂应当使用静态方法。
总结
还是不能直接把字符串作为内部表示。内部数据的管理应当抽象出来。
oo第一次作业的更多相关文章
- OO第一次作业总结
OO第一次学习总结 1.第一次作业:多项式加法 从未接触过java的我,在从输入输出开始学了几天后,按照C语言的思路,写出了一个与面向过程极其接近的程序. 在这个程序中,存在两个类:一个是Comput ...
- 从入门到不放弃——OO第一次作业总结
写在最前面: 我是一个这学期之前从未接触过java的小白,对面向对象的理解可能也只是停留在大一python讲过几节课的面向对象.幸运的是,可能由于前三次作业难度还是较低,并未给我造成太大的困难,接下来 ...
- OO第一次博客作业
OO第一次博客作业 一.三次作业的bug反省 1.自己发现别人的问题 (1)输入处理的问题,比如第一次作业,主要就是处理输入的字符串,然后有同学的正则表达式有问题,则对于一些错误输入就不能正确判断. ...
- OO第一次博客作业--第一单元总结
OO第一单元总结 面向对象设计与构造的第一单元,对“面向对象”的概念还根本不理解不熟悉,只觉得需要“分模块”,但不知道怎么分,分多少模块,怎么根据需要的模块的功能建立类.学习的进度又太慢,根本跟不上出 ...
- oo 第一次博客作业
oo 第一次博客作业 早在大一就听说了oo的各种传奇故事,大二下学期终于也开始了我的oo之旅. 基于度量来分析自己的程序结构 第一次作业 类图分析 耦合度分析 可以看出在第一次作业中,我的耦合度非常高 ...
- 2018 OO第一次总结(作业1-3)
第一次作业1.程序分析 (1)OO度量 (2)类图: (3)分析与评价: 这次作业由于作业整体设计难度不大,因此按照去年暑假上的OO先导课老师讲的设计方法很容易实现一个还不错的面向对象式程序,类与类之 ...
- OO第一次总结作业
第一次OO博客作业 前言 面向对象课程已经经过了4周的时间.前三次作业全部是关于多项式求导的相关内容,内容由易到难,同时我也开始逐渐深入感受学习面向对象的各项特征,逐渐将自己的编程风格从C向真正的面向 ...
- OO第一次博客作业总结反思
使用了masteruml插件来生成类图和metrics插件分析代码 第一次作业 1.UML类图 >在第一次作业中,使用了两个类,代码中有没有使用的变量与函数,为平衡两个类的内容,我将输出函数放在 ...
- OO第一次博客作业(第一单元总结)
Q:菜是绿的,鸡是黄的,那菜鸡是什么颜色的? A:红的,强测全WA了,能不红么. 菜不菜的问题先不说了,认真研究一下这次的题目,以及WA的原因吧. 程序结构简析 三次实验的核心结构都是差不多 第一次的 ...
随机推荐
- 关于python3.6上传文件时报错:HTTPSConnectionPool(host='***.org', port=443): Max retries exceeded with url: /post (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAIL解决办法
第一个报错: 最近在练习post请求中上传文件时遇到了一个奇葩事情,两台电脑上写了一模一样的代码,一个运行正常,另一个一片红. 最后了解了一下原因以及解决办法.先记录下关键代码: files = {& ...
- react-native 引入某些低三方库时出现的Command `run-android` unrecognized,命令不识别错误
在使用第三方库时react-native-swiper,执行 npm install react-native-swiper --save 再次运行react-native run-android时直 ...
- Android系统源代码目录结构 “Android源代码”“目录结构”
在讲述Android源码编译的三个步骤之前,将先介绍Android源码目录结构,以便读者理清Android编译系统核心代码在Android源代码的位置. Android源代码顶层目录结构如下所示: ├ ...
- Python3的桌面程序开发利器:Eric6的环境搭建、使用
本文旨在通过一个简单的demo,介绍基于Python3.PyQT5的环境下开发桌面应用程序的一种方案,当然开发Python的桌面应用程序不止是PyQT 这一种方案,还可以使用Python自带的Tkin ...
- Lesnoe Ozero 2017. BSUIR Open 2017
A. Tree Orientation 树形DP,$f[i][j][k]$表示$i$的子树中有$j$个汇点,$i$往父亲的树边方向为$k$的方案数. 转移则需要另一个DP:$g[i][j][k]$表示 ...
- 关于Android studio 设置点击打不开的解决
今天早上觉得字体太小了想改下字体发现设置点不开,后来发现是打了汉化包的bug,后来换了一个汉化包就能打开了.
- 浅谈AngularJS中的指令和指令间的相互通信
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- 面试题: 多个 await 处理,有一个失败,就算作失败
面试题: 多个 await 处理,有一个失败,就算作失败 ? Promise.all([p1, p2, p3....]) // 返回的也是一个 Promise 对象 -------- asait ...
- tomcat错误The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
在更换tomcat版本后,原来的项目文件中jsp会出现错误The superclass "javax.servlet.http.HttpServlet" was not found ...
- Dev_GridView获取所选行的句柄
这是官方帮助文档上的一句话: 此示例演示如何获取所选行,然后更改其字段值. GetSelectedRows方法检索所选行的句柄. 由于行句柄反映了在View中显示行的顺序,因此修改单行可 能会影响其他 ...