OO第一单元总结
前言
在经历了三周相对痛苦的面向对象课程的学习之后,终于有了机会进行一次总结。说实话经过了三周的学习,还是收获了不少东西的。
第一次作业
程序分析:
这次作业是我的第一次OO作业,其中只有四个类,分别是主类、中间类、判断类和求导类。
设计思路:首先应用一个主类进行数据的输入和输出工作,然后中间类负责进行数据分离,接收求导结果等等,判断类负责进行格式判断,求导类负责进行求导。
优缺点:事实上这次作业应该还是用面向过程的思想在写,把需要完成的大功能放在一个相对独立的类当中。但是这样的设计可能对于当时的我相对容易想到,也比较容易实施。在这个相对简单的任务中,这样的设计方法可以减少代码的数量,但是不利于思维的抽象等。
发现bug:第一次作业给了我一个极其惨痛的经历。因为没有使用BigInteger类进行数据的计算,导致自己在强测试中错了5个点,并没有进入互测环节。到目前为止,我也只发现了这一个bug,可以说非常惨痛。从此之后,下两次作业我都会使用BigInteger来处理指数和系数了。
结论:第一次涉及虽然有很多不完美的地方,但是,在下两次作业中我还是保留了用来处理输出错误情况的类,还有求导的类,但是具体的实现方法和思路已经完全不一样了。
第二次作业
程序分析:
第二次作业采用了六个类,但是其实分的还是非常杂乱的。主类、判断格式类、中间类、拆分成项的类、项中进行整合三元组的类以及求导类。
设计思路:首先应用一个主类进行数据的输入和输出工作,然后还是利用格式判断类进行WF形式的判断。中间类作为一个中转站,在这里进行声明其他的类,获取处理数据的结果,最后将一个ArrayList类传回Main进行输出工作。拆分成项的类用来把一个完整的表达式拆分成项,即几个乘号连接的表达式形式。项拆分类是用来把项进行处理,变成一个四元组,即系数,x项指数,sin项指数,cos项指数。最后进行求导操作。
优缺点:这次的设计实际上还是比较面向过程。按照需要完成什么功能,就设计一个大类,然后构造一些方法来实现这一功能。在构造的过程中,我在项变为四元组的环节,采用了系数相乘,指数相加的方式。先对表达式进行化简,得到一个四元组,然后再进行求导,从而减少求导部分的代码量。这样的设计对于第二次作业这种仍然不是非常复杂的情况依然比较容易实现,但是其实还是不是利用面向对象的思想进行抽象。说实话,自己觉得我的三次作业都没有使用特别明显的面向对象思维方式,不过在逐渐改变。
发现bug:这一次自己的bug比较多。首先自己遇到了求导的时候将系数写错的情况,导致很多强测试点发生了输出错误的情况。同时,在互测中,好多同学也发现了我的代码存在一个问题。我的输出部分是按照项进行输出,也就是每处理一个项就输出一个项,但是如果之前的项是正确的,之后有错误项,就会先输出正确项,再输出WF。针对这种情况,我将其改正为首先判断表达式合不合法,再进行逐项计算输出。
然后说说自己在给别人debug时候发现的问题,首先就是有人存在着格式判断的问题。然后还有,在阅读别人代码的过程中,我发现有些人没有先把两个符号连在一起的情况进行预处理,导致它的代码在特定情况下可能读入表达式的时候出现错误。
结论:在第二次作业中,我简化了求导部分,将其变为纯四元组然后用BigInteger类的数字表示,最后再进行数字向表达式的转换。同时把拆分做成了两个独立的类,但是感觉仍然缺少真正的面向对象的设计思想。
第三次作业
程序分析:
第三次作业采用了5个类,还是有些少...开始时候真的摸不到头脑。主类用来进行输入输出的操作。判断类用来进行常规的判断操作还有判断括号匹配,判断某一部分表达式是否是一个项。静态类存储可能会用到的静态变量。因子类用来进行分析因子种类,及可实现对应的求导。表达式求导类用来真正实现分解和递归求导的部分。
设计思路:首先应用一个主类进行数据的输入和输出工作,然后还是利用格式判断类进行WF形式的判断,其中需要判断的错误情况等在Const常量类中已经全部列举。然后将表达式丢给表达式求导类中,表达式求导类会先判断当前的输入的类型,根据类型,调用不同的方法进行递归求导。当递归进行到最后的因子项时会调用因子求导类中的相应方法具体求出导数。
优缺点:这次设计原本还是打算完全按照PPT中给出的图来实现,但是可惜绞尽脑汁也没有想出来。最后采用了一种介于过程和对象之间的方法,没有单独为每一种函数建立一个类,但是有一个因子求导的类专门用来处理这种最基本的函数,其余部分用一个表达式求导类进行递归求导,比较直观。但是在递归求道的过程中,只建立了一个类,在调试的过程中面临了很大的困难,比较容易搞晕逻辑顺序等等。
发现bug:自己遇到了求导的时候将系数写错的情况,这已经是我遇到的第二次了。但是这次引起的原因稍有不同。因为此次为了便于分离嵌套项,我采用了捕获组的方法,这次捕获组使用中不够小心,导致在次数为二时,应该只捕获不含次数的部分,但是我捕获了整个表达式,造成了自己的错误。
结论:在第三次作业中,基本完成了按照面向对象的思想来解决问题,虽然仍然存在非常多的不足,但是总体上相比于第一次和第二次还是有一些进步的。第三次作业的递归求导让人感觉有很大的难度。
Applying Creational Pattern
说实话自己这几次的代码是一点一点从面向过程向面向对象慢慢靠近。如果可以的话,我认为应该把函数求导的部分抽象成每一种函数看成一个类。在分离后通过正则表达式进行判断类型,然后进行求导。
也许这样自己会写起来方便一些吧。