第一次作业
UML类图
耦合度
BUG
无
简述:
第一次作业比较简单,分别实现输入、求导、输出三个任务并用map去重即可。
第二次作业
uml类图
类耦合度
BUG
无
简述:
只分了两个类,input完成所有输入并生成Monomial类的工作,Monomail完成求导、化简和输出,因为大量代码压在了两个类里,导致两个类复杂度都很高。
第三次作业
uml类图
类耦合度
BUG
互测阶段一个bug:小括号前的符号只会被作用于括号内第一个项。
强测阶段一个bug:对于偶数次幂的sin会错误的把sin括号内的负号变成整个sin的负号。
简述:
考虑到这次代码比较长,先完成了一个保证正确性的程序,后在此基础上化简,架构上沿用了前两次的架构,一个类负责输入并创建类,另一个类负责求导输出优化。考虑到这次任务比较复杂,先在纸上写出来比较详细的程序架构才动手。优化部分没有做太多,主要是写了加法乘法向一侧退化、sincos退化成常数以及去括号三个部分。
反思:
架构上实际上把sin cos x 常数 加法 乘法 六类暴力的塞进了一个类,因为我是提前在纸上设计的架构,实现时没有造成太大的麻烦,但是一个类太长了非常不美观,图表数据很难看,另外多出来很多冗余的对象。
结构上另外一个问题是我把化简和输出放在了一个过程中完成,让这个过程变得非常复杂,同时也限制了我的优化空间。对于表达式树这样一个结构来说,括号一般在输出过程中产生,所以去除冗余括号正负号等细节可能必须在输出过程中完成,但是合并同类项、退化等工作可以另外进行,否则退化和合并同类项通常要重新考虑生成子树的字符串。因此可能应该适当的分离优化和输出。
设计上每个结点用一个boolean型变量tag来表示是否有多余负号,主要是为了去除冗余括号,程序的两个bug都与这个设计有关。第一个bug问题在于设计加法运算时用tag表示前向的负号,后项的tag不保存,只在生成的输出字符串中用“+-”表示。这个架构本身是没有问题的,因为-p等价为-1*p。另一个bug是由于写化简时忘了sin是支持幂函数的。
出现的两个bug确实都在我的思维盲区范围内,只能说测试工作不到位,测试方法主要是复用了第二次作业数据生成器对拍加上自己手出的带有嵌套的数据,事后看来盲区比较大。
互测
这三次作业的互测我都是采用对拍器黑盒测试的方式找bug,这个方式的比较大的问题就是不知道找到的bug是不是重复的,而且第三次组内的两份代码由于种种原因无法自动测试。
第一次没有发现bug,第二次发现了两位同学的bug,第三次发现了三位同学的bug。
重构
事后看两个类的简单架构只适用于第一次作业,后两次作业的架构相比任务来说过于粗暴。第三次作业应在Poly下建立六个子类sin、cos、常数、x、+、乘,并分别实现toString,read,求导等函数。应该可以解决Poly类复杂度飘红的情况,input类主要做的是面向过程的一些琐碎工作,应按功能拆分,将判断WF、标识符替换、生成Poly类分开,让代码结构更加清晰易懂。
对比和心得
动手前要设计好架构,不然可能会边写边重构。写完了要有比较系统的测试,否则功能复杂的代码很容易有意料之外的bug