第一单元 oo 的作业已经结束, 3 次递进式的编程作业和 2 次实验课作业让我们初步体会到了面向对象的思想, 以下对本人在第一单元中的三次作业进行分析和总结.
一, 三次作业的结构分析
1, 类个数及长度分析
第一次作业
第二次作业
第三次作业
从图中可以直观的看出, 第一次作业中只有两个类, 说明当时对面向对象的思想还相当不了解, 更多的是像之前一样面向过程, 针对给出的问题一步步寻求解决的方案; 而第二次作业类的数目就增加到了 6 个, 已经开始尝试去面向对象编程, 把多项式求导分解成了对多项式这一类具有相似特征的一系列操作, 多项式类, 求导类, 合并类...... 还增加了老师建议的 InputHandler, 已经开始按照面向对象的思想分析问题; 第三次作业的这一特征更加明显, 递归下降使得类与类之间有了更密切的联系, 表达式 -> 项 -> 因子, 功能的实现在类的内部, 类之间依赖于信息的传递.
代码的长度由第一次的 450 行到第二次的 720 行再到第三次的 700 行, 实现的是越来越复杂的功能, 后面的程序支持前面的程序, 第三次因为类之间的配合更密切以及优化写的比较粗糙(泪...), 其长度反而比第二次要短.
2, 复杂度分析
注:
ev(G)基本复杂度.
iv(G)循环复杂度.
v(G)整体复杂度.
第一次作业
第二次作业
第三次作业
从以上的表格可以看出, 我每次作业都有几个方法的复杂度偏高, 而且绝大多数都是 iv 偏高, 分析原因, 在这些方法中都用了较多的 for 循环, 以及极多的 if-else 语句, 这就可以看出我在分析问题时习惯于穷举可能发生的情况, 这就导致了在情况多的时候方法的复杂度会较高, 今后可能需要尝试更为有效的解析问题的方法.
3, 类图分析
第一次作业
第二次作业
第三次作业
三次作业的特点非常鲜明, 第一次作业中只用到了两个类, 也只是在 main 调用了 poly , 这也直接导致了我第二次作业的完全重构; 第二次作业类与类之间的关系也非常不密切, 只是通过主类依次调用各个类来实现目的; 而第三次作业中, 类与类之间就有了联系, 通过主类来调度, 在 Item 和 Poly 这两个类之间递归直至发现了最基本的因子, 再去调用因子对应的类. 和其他人的程序比较发现, 在我认为我以及很面向对象了的情况下, 一些共同的功能 (如求导) 我没有用接口的方式去解决, 也就是我在 3 次作业中并没有用到接口, 可见还是没有熟练的掌握面向对象的思想.
二, bug 分析
1, 第一次作业
第一次作业中出现的 bug 是没有考虑出 < space > 和 < tab > 之外的空白字符, 这个在修改时只需要把正则中用到 \\s 的地方改为 [\\t ]即可.
2, 第二次作业
第二次作业中的 bug 比较严重, 没有考虑指数中带 + 号的情况, 因为我在分割的过程中用 + 号作为了分割符对项进行分割, 就导致了会出现异常, 我在修复时采用了在判断合法的前提下把 ^+ 替换为 ^ ; 还有一个 bug 出现在我的优化, 我在优化之后可能把一个表达式优化为常数, 而常数不可再次优化, 这就导致会出现异常(无辜的眼神), 我在把优化前的表达式进行了判断, 解决了这一问题.
3, 第三次作业
这次作业 bug 未知.
三, bug 发现策略
前两次作业中, 我因为没有使用正则判断表达式是否合法, 而是采用了状态机的方式, 因此我清楚各种应该输出 WF 的情况(所有情况:)), 在测试的时候我先用这些数据盲测了一波, 就能发现几个问题, 然后挑两个倒霉的孩子学习他们的代码(找 bug), 读完的结果就是膜或者发起进攻.
第三次作业我也用了前两次作业的方法, 由于 WF 被禁止了, 并没有发现 bug, 除此之外还用了评测机的方式, 这个就相当有效了, 当然, 为了做个人, 见好就收.
四, Applying Creational Pattern
与一份优秀的面向对象的相比, 我的还差很多, 虽然我大致理解面向对象的思想, 但在我 3 次作业中, 都没有用到继承和接口, 所以有极大的重构空间, 可以使那些相互依赖性强的类从一个父类继承下来, 然后把一些共同具备的功能 (主要指求导) 用接口实现, 这样就能使代码更加面向对象了. 在面向对象课程的学习上我还有很长的路要走, 希望在接下来的过程中, 能够对面向对象的思想有更深的理解吧.
来源: https://www.cnblogs.com/ring-of-sun/p/10604665.html