OO第一单元总结
OO第一单元总结
程序结构分析
第三次作业架构分析
第三次作业设计思路
首先建立基础类:Poly
,Term
,因子类(Factor
类),树类(Der
类),所有类都继承求导接口Der
,实现求导方法der()
,首先在FuncFactory
类中解析输入的表达式,先删除多余括号降低表达式因子深度,再将嵌套因子sin|cos(fac)**num
替换为sin|cos#**num
,表达式因子(fac)
替换为@
,生成对应的表达式因子类FacPoly
以及嵌套因子类DerNest
储存在工厂类的容器中,用于求导时替换。判断替换后的poly
以及替换为@、#
前的内容是否满足正则表达式以判断是否为WRONG FORMAT!
,再解析替换后的poly
,提取其中所含的各项并存储在ArrayList<Term>
内,同时每个Term
类提取了其中所含的各因子并存储在ArrayList<Factor>
内,之后调用根节点Poly
类的der()
方法建立树tree
并求导,返回字符串der
。
第三次作业类图
第三次作业复杂度分析
代码规模分析
- 部分因子类以及树类代码过于繁冗,原因是求导过程中
if
分支语句过多。 - 工厂类代码量明显大于其他类,由于各种解析、优化、正则表达式的存储都在工厂类中进行。
- 未很好的进行代码复用,部分方法重复度极大,如
WF
判断与替换嵌套因子与表达式因子的两个方法差别仅为前者不将获取的因子添加到工厂容器中。
类复杂度
方法复杂度
- 类复杂度与方法复杂度较高,体现出代码耦合度较高。
- 大量的分支语句以及方法嵌套调用,如乘法求导过程中的直接优化需要判断是否有因子求导为
0
或1
等,不断嵌套调用toString()
或der()
方法,同时也使代码维护难度加大。 - 采用递归向下的解析模式,对于求导操作层次化的处理便于功能的迭代,如第二次作业向第三次作业迭代只需增加相应的嵌套因子类
DerNest
以及在解析输入表达式时增加替换方法等。
bug分析
第一次作业通过强测,在互测阶段并未hack或被hack成功。第二、三次作业只针对自己代码的bug进行修复,故分析自身代码bug产生原因以及解决办法。
自己产生的bug分为三种:
-
WF
未判断成功:在对嵌套因子内容判断时,只针对格式为含有外侧括号的字符串进行了处理,而遗漏了如同sin(+ x)
的情况,故只需增加无外侧括号的分支即可。 -
格式错误:由于编写各个类的
der()
方法时,分支语句过多,眼花缭乱,导致遗漏括号、正负号等,导致输出的导数中,出现sin(-fac)
、(-sin(x)cos(x)
等奇怪的情况,同时在简化时也未考虑输出的三角函数内部因子前不能有正负号,仔细查缺补漏即可修复。 -
求导错误:由于正则表达式中因子前正负号放置位置出错,导致在
|
分开的多种因子中,只有第一种因子前的正负号会被读取,故将正负号提前至所有因子前即可。综合后两次作业产生的bug,表现出自己对指导书的阅读不仔细、面对复杂情况时写代码的粗心大意,导致在条例清晰的设计图下仍然建了一个豆腐渣工程。
心得体会
三次作业迭代的过程中并未进行大规模的重构,面向对象思想下的构建可拓展性是肉眼可见的好。通过本单元,切身体会到通过接口能够实现多种类功能的统一,从而实现“因地制宜”,在引用时将所有对象抽象为一个接口,再通过统一方法的调用,就能自动根据对象自身类的不同来实现想要的功能,其层次性明显优于面向过程的编程模式。体会到了面向对象程序设计的优点,但在具体编程中还是有所不足,在这个单元中出现了很多bug,虽然修复过程十分顺利,但是也体现出了自身的问题,同时对于求导优化没有做到最好,这也是一个不足之处。
第一单元的收获还是很大的,今后依然要认真地完成OO作业,希望在今后的学习中能够收获满满!