OO第一单元总结
Unit1总结
一、程序结构分析
hw1是简单幂函数的求导,我的设计完全脱离面向对象的思想,写了一个term类,直接按a*x**b的形式提取系数与指数,以<系数,指数>保存在hashmap中。
hw2新增幂函数与三角函数乘积项,我依然没考虑扩展性,套公式进行“强行求导”。
(a*x**b*sin(x)**c*cos(x)**d)' = a*b*x**(b-1)*sin(x)**c*cos(x)**d + a*c*x**b*sin(x)**(c-1)*cos(x)**(d+1) - a*d*x**b*sin(x)**(c+1)*cos(x)**(d-1)
hw3新增了三角函数内嵌套因子,我沿用了套求导公式的策略,设a,b...,k是因子
(a*b*c*...*k)' = a'*b*...*k + a*b'*...*k + ... + a*b*...*k'
然后将factor分为符号整数类,幂函数类和三角函数类,实现toString和diff方法,分别返回原型字符串和导函数字符串。涉及三角函数嵌套,就new一个Expression,调用Expression.diff得到内层导数。
Term类中包含了各种Factor,负责用'*'和'+'将各个因子或因子的导函数按求导公式连接起来,并负责大部分优化,如省略零因子(项)。Expression类中包含了Term类,实现了diff方法用于递归。
荣老师在研讨课上说,“世界是异步的,物体之间依靠消息进行沟通”。计算机学科中的“消息”有很多形式,可以是高低电平,可以是01标志位或数据流,etc。
在Unit1中我实际上只构造出了factor,term,expression零零几个的物体,他们相互交流的消息就是toString返回的原型字符串和diff返回的导函数字符串。得力于比较清晰统一的“字符串消息”设计,花了不算多的时间顺利实现了所有需求,但这已经是非常勉强的,一旦要新增一个arctan因子,Expression类及term类都要修改正则表达式,Factor要新增一个子类,行为和三角函数类高度相似,可以考虑泛型接口如下
public interface Nesttype<T> {public String diff(T);}
二、bug分析
为了在满足所给题目要求的情况下偷懒,我增加了方法的类内方法的耦合度,请见hw3中Term的丑陋的构造函数
正由于方法之间存在不小的耦合度,实际上是拆分了本应独立存在的方法的功能。这就导致在手动构造测试样例的时候,不能明确测试样例的特异性。比如我将WF判断的功能分散到Expression和各个Factor中,共计5个类9个方法设计到WF的判断,这就导致最后没能测出,子表达式因子内的空白字符可能引起的WF问题。
我反思课程组所说的对加法乘法运算统一建模的思路,也有出于这方面的考虑,即规范对象之间的消息交流行为,将功能统一化规范化。
三、重构设想
为什么要对加法乘法运算构建对象,他们既有自己独特的求导规则,又是构成项和表达式的重要因素。每个运算符可以包含两个运算对象的属性,即因子或项。应当可以进行求导,化简(合并同类项)等行为。
class Mult{Factor a; Factor B; String diff();String simp(); }
四、体会