首页 > 技术文章 > OO第一单元总结

nebulau 2019-03-24 21:22 原文

第一单元的作业为多项式求导,在迭代作业中学习了:对象特性、OO构造机制和层次化设计,在bug互测环节也学习到很多巧妙的设计。

第一次作业

 设计了三个类:Term、Derivative和ReportExit,分别处理项、求导和报错退出,如今回头看有很多设计不合理的地方,例如在Term构造方法中直接解析表达式并设置成员变量。

类图:

代码度量:

 由于在main方法中也对输入表达式进行了正则解析,Term类构造方法也对表达式进行了解析,导致iv(G)和v(G)值过大。由于对于方法过长粗暴Refactor也导致结构有点混乱。

bug集中在非法字符的判断,由于每次继续处理直接str.trim(),导致非法字符被过滤掉。

hack到的bug也集中在非法字符上。

第二次作业

第二次作业已经有了有点层次化的结构,建立了5个类:Factor,Main,Poly,ReportExit,Term,分别处理因子、表达式、项,有了第一次作业的经验,结构稍微好了些。

类图:

代码度量:

可以看出仍有些方法复杂度较高,各类之间的耦合度比较正常,在Poly,Term和Factor自顶向下分析字符串,并返回处理后的字符串,统一有个Process函数,Term.Process复杂度较高是因为在这个方法里面循环读取当个因子直到下一个字符不是*。

同时在Poly的构造方法中也是因为直接处理表达式导致复杂度过高,因子的求导方法Derivative方法复杂度过高是因为将几种因子的求导囊括在了一块。

采用这种层次化设计思路比较清晰,但是对于优化很不友好。算是有得有失。

第三次作业

对于第三次作业构思了很久,因为出现了递归和嵌套的情况,尝试建立表达式二叉树来对节点进行运算,后来发现递归下降处理也能实现相应的效果,沿用了第二次作业的整体架构,对几种因子增加了三个接口:Parser,Derivation和printString

分别负责表达式解析,求导和打印的功能。整体思路依旧以因子为最小的识别单位,以*和±判断出项和表达式,Parser如果解析出相应的因子,项或者表达式即返回处理后的表达式,反之返回原表达式。

类图:

代码度量:

层次化设计使得类间耦合度比较正常,依旧有几个方法的复杂度稍高,主要是表达式解析器和求导方法。

层次化设计思路清晰,但是优化难度大,直接放弃结果合并优化。

bug发现3处bug,对于表达式打印自身没有考虑每个项的符号;三角函数嵌套时多打印出了指数;表达式非正常结束没有判退出导致Crash。

由于没有多余时间,仅hack了别人1个bug,嵌套情况没有考虑全。

Applying Creational Pattern

分为  创建型模式(Creational Pattern) - 工厂模式(FactoryMethod) 

此三次作业均采用创建型模式(Creational Pattern),在第三次作业中采用了接口,用相应对象实例化:

Calculate factor1 = new Const();
Calculate factor2 = new PowerTrigFun();
Calculate factor3 = new Expr();
Calculate factor4 = new Nest();

总结

对于解析器Parser返回类型的设置不合理,常用返回应该是一个类。同时也体会到了接口的便捷性和对归一化处理重要作用。优化对于一个程序运行而言也至关重要。一个很好的前期构思往往起到事半功倍的效果。

推荐阅读