OO_JAVA_表达式求导_单元总结
OO_JAVA_表达式求导_单元总结
这里引用个链接,是我写的另一份博客,讲的是设计层面的问题,下面主要是对自己代码的单元总结。
程序分析
(1)基于度量来分析自己的程序结构
第一次作业
程序结构大致如图:

结构比较简单,只有三个类,分别是Main,Polynomial和PolynomialItem。
方法复杂度分析如图:

可以见得:主要是类的构造方法和toString方法复杂度较高,因为要面面俱到。
第二次作业
程序结构大致如图:

程序结构比较简单,只有六个类。
方法复杂度如图:

可以见得:由于是在表达式和因子的类之外建立的求导方法类,Diff类的求导和化简函数复杂度都很高;然后就是因子Factor的构造方法和toString方法以及Item的构造方法复杂度很高;再其余就是ExprProcess处理类复杂度很高。
Diff类和ExprProcess类内部都是静态方法,这样设计是来自过程式编程,采取一个函数处理不需要自己独立的属性,即不需要建立一个类,直接使用其静态方法,静态方法其主要工程用途应该是作为工厂函数,如此写作是滥用,我已经意识到了。
第三次作业
程序结构大致如图:

这张图表明,Atom与其子类是关系紧密的,其它在逻辑上较为分离的。
所有的Atom子类都继承自Atom父类,这在设计上是不可取的,依赖度太高,不应该是extends继承的真正用法。
Atom父类包含了所有子类所需属性和方法,也不合理。
方法复杂度如图:



首先列举一下复杂度较高都是些什么方法:
- ExprProcess静态方法类,由于依旧是与第二次作业类同的组合方式,写出了这么个静态方法类,造成了单一方法巨大的复杂度,应该按照我在我开头引用的我的博客链接里的Parser的写作方法,把复杂度分散到不同Parser接口实现中,但是这基本上是我第三次作业写完了才学到的方法,所以没有运用;
- AtomFactory类的两个静态方法,这是我为了集约式根据枚举类型创建子类而编写的,复杂度高情有可原;
- PlusAtom和MultiAtom的Merge方法,因为处在合并同类项层次,故而要处理的类很多,所以复杂度极高,是属于可以拆分的;
- Atom类内部一系列跟合并化简相关的函数,因为其写作在顶层父类Atom中,又牵涉各级子类,复杂度较高:
- couldBeMergedAroundPlus和couldBeMergedAroundMulti两个函数,我的Predicate接口,用来判断两项是否能被合并,还没有有效的构建方式,涉及子类有比较多,所以复杂度高;
- equals方法:为上述两个函数准备的,依旧是处于父类,所以方法复杂度较高;
- expand和flatMap方法:依旧是为化简准备的,但是写在父类,不可避免地发生了比较高的复杂度。
(2)分析自己程序的bug
表达式求导的第一次作业比较简单,中强测和互测没有叮出bug;
第二次作业的bug问题主要是缩略空白字符时,正则表达式漏了+号表示替换一片空白为一个空格,因此出了正确格式误判为WF;
第三次作业优化部分有很大的bug,除此之外,在正常处理部分,漏算了一条Scanner的hasNext方法会略去最后的空白字符,应该提前trim掉,改了这个bug并删去优化的调用,就修完了,也就是说正常处理部分是这一个bug。
总体来说最容易出现bug的位置还是输入处理和优化这两部分,输入是业界老大难,毕竟很难保证用户不会某一个异常输入爆掉你的程序,所以这部分处理由于思维的局限性、不连贯性,很容易出现疏漏,而优化部分,很容易因为过于复杂的逻辑产生代码中的隐蔽问题,可能简单的样例没有问题,但是稍微精心的样例就可以爆掉。。
这就说明,逻辑越内秉,越聚合在一起,就越容易出现bug,输入处理和优化都是这样。
所以设计类、接口的层次结构时就必须考虑这个问题,分散逻辑。
从树的角度,我设计的类有个很大的问题就是父类实现了所有的方法,太累赘太复杂了。。。
(3)分析自己发现别人程序bug所采用的策略
我没有采取研究别人代码或是正则的方式寻找bug,属于随心随机地写一些数据找别人的bug,因为第二次作业犯了小错误,第三次作业交了优化版本还有其它的小疏漏,应该是被分到C组这样,所以随机地构造一些数据我就找到了很多别人的bug,但是第一次作业就不行了,在结构非常简单的前提下,要找bug就必须深入细节或者是大批量测试才行。
我的主要随机构造思路就是尽可能嵌套多一些,空格随机加一些,主力寻找别人把正确格式误判为错误格式这样的bug。
(4)Applying Creational Pattern
前两次作业由于类的数目在设计上就比较稀少,第一次3个,第二次6个,在编程上并没有学会或者是意识到要运用什么设计模式;
但是第三次作业达到了空前的突破,达到了17个类,这时我也意识到了工厂方法,可以更加灵活地创建对象,并私有化构造器,如果现在让我设计,第三次作业的表达式树部分的类,我一定会采用统一定义接口的方式,实现接口的类都添加工厂方法,以此来梳理结构,减轻父类甚至去除父类。
OO_JAVA_表达式求导_单元总结的更多相关文章
- OO_JAVA_表达式求导
OO_JAVA_表达式求导_第一弹 ---------------------------------------------------表达式提取部分 词法分析 首先,每一个表达式内部都存在不可 ...
- OO_多项式求导_单元总结
概述: 面向对象第一单元的作业是三次难度依次递增的多项式求导.第一次作业是仅包含带符号整数和幂函数的多项式求导,例如:-1+xˆ233-xˆ06:第二次是在前面的基础上增加了三角函数的求导,例如:-1 ...
- BUAA-OO-第一单元表达式求导作业总结
figure:first-child { margin-top: -20px; } #write ol, #write ul { position: relative; } img { max-wid ...
- 2019年北航OO第1单元(表达式求导)总结
2019年北航OO第1单元(表达式求导)总结 1 基于度量的程序结构分析 量化指标及分析 以下是三次作业的量化指标统计: 关于图中指标在这里简要介绍一下: ev(G):基本复杂度,用来衡量程序非结构化 ...
- 2020 OO 第一单元总结 表达式求导
title: BUAA-OO 第一单元总结 date: 2020-03-19 20:53:41 tags: OO categories: 学习 OO第一单元通过三次递进式的作业让我们实现表达式求导,在 ...
- 面向对象第一单元总结:Java实现表达式求导
面向对象第一单元总结:Java实现表达式求导 题目要求 输入一个表达式:包含x,x**2,sin(),cos(),等形式,对x求导并输出结果 例:\(x+x**2+-2*x**2*(sin(x**2+ ...
- OO_Unit1_表达式求导总结
OO_Unit1_表达式求导总结 OO的第一单元主要是围绕表达式求导这一问题布置了3个子任务,并在程序的鲁棒性与模型的复杂度上逐渐升级,从而帮助我们更好地提升面向对象的编程能力.事实也证明,通过这 ...
- OO_JAVA_电梯运行模拟_单元总结
电梯运行模拟--三次作业总结 目录 电梯运行模拟--三次作业总结 总体遵循的设计思路 逻辑解耦 电梯与调度器解耦 楼层信息的存储和变更与电梯.调度器解耦 调度器运行流程解耦 第一次电梯,蠢笨串行先到先 ...
- OO Unit 1 表达式求导
OO Unit 1 表达式求导 面向对象学习小结 前言 本博主要内容目录: 基于度量来分析⾃己的程序结构 缺点反思 重构想法 关于BUG 自己程序出现过的BUG 分析⾃己发现别人程序bug所采⽤的策略 ...
随机推荐
- SVN无法查看最近日志和提交记录
现象: 使用SVN查看最近的提交记录日志时,最近总是无法显示出全部的日志内容,只能显示到几天之前的日志.就算是自己刚提交的代码也是无法没有记录的. 解决方式:右键选择TortoiseSVN中的&quo ...
- 掌握基于AOP事务管理
一.手动管理和半自动工厂模式 二.AOP事务管理 1.表达式中,第一个※是返回值所有类型,service包下一个点意思是service包下的类,两个点意思是service包下的类和其子包下的类也包含, ...
- 自定义-starter
目录 说明 编写启动器 新建项目测试我们自己写的启动器 分析完毕了源码以及自动装配的过程,可以尝试自定义一个启动器来玩玩! 自动装配的过程 SpringBoot-静态资源加载-源码 SpringBoo ...
- 聊一聊开闭原则(OCP).
目录 简述 最早提出(梅耶开闭原则) 重新定义(多态开闭原则) 深入探讨 OCP的两个特点 对外扩展开放(Open for extension) 对内修改关闭 抽象 关闭修改.对外扩展? 简述 在面向 ...
- 聊聊ReentrantLock基于AQS的公平锁和非公平锁的实现区别
ReentrantLock锁的实现是基于AQS实现的,所以先简单说下AQS: AQS是AbstractQueuedSynchronizer缩写,顾名思义:抽象的队列同步器,它是JUC里面许多同步工具类 ...
- Java集合:HashMap
Hashmap是一个存储key-value的映射表. 优点: 索引数据快,查找一个数据对的时间复杂度是O(1) 增加.删除一个数据的时间复杂度是O(1) key不能重复,可以存储一个null值 存储: ...
- 使用manacher算法解决最长回文子串问题
要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...
- MySQL之索引复合索引有效性
首先这里建立一张数据表,并建立符合索引( index_A,index_B,index_C) CREATE TABLE `test_index_sequence` ( `Id` int(11) NOT ...
- whistle浏览器抓包(以火狐浏览器为例)
环境:whistle:1.14.6 whistle浏览器抓包 以火狐浏览器为例 1.启动whistle 使用w2 start启动whistle. 退出cmd后,whistle自动关闭了,所以每次使用w ...
- sessionId在小程序中的妙用
前言:小程序发送短信验证码需要在后台储存生成的code,一次会话应放入session中,请求头部发送sessionId验证为同一session 1.页面一加载就从后台获取sessionId,储存在本地 ...