• Summary of OO Unit1


    本单元共有三次作业,分别为:

    HW1:实现对仅包含简单幂函数的多项式的导函数求解。

    HW2:实现对包含简单幂函数和简单三角函数的多项式的导函数求解。

    HW3:实现对包含简单幂函数、简单三角函数、复合函数的多项式的导函数求解。

    一、code analysis

    先回顾一下三次作业的UML类图和Complexity metrics。

    HW1

    HW2

    HW3

    HW1

    class OCavg WMC
    Poly (color{red}{5.67}) 17
    Term 2.00 10
    MainClass 1.00 1
    Total 28
    Average 3.11 9.33

    HW2

    class OCavg WMC
    Poly (color{red}{4.75}) 19
    Term (color{red}{3.73}) (color{red}{56})
    TypeX 2.25 9
    TypeSinx 1.75 7
    TypeCosx 1.75 7
    Regex 1.00 9
    MainClass 1.00 1
    Total 108
    Average 2.63 15.43

    HW3

    class OCavg WMC
    Poly (color{red}{5.42}) (color{red}{65})
    Term (color{red}{4.64}) (color{red}{65})
    TypeX 2.20 11
    TypeSinx 2.20 11
    TypeCosx 2.20 11
    Regex 1.00 14
    MainClass 1.00 1
    Total 178
    Average 3.18 25.43

    可以看到,三次作业下来,代码的耦合度基本处于直线增长的情况,程序变得越来越臃肿。究其原因,是自己不愿试错和探索,始终没有尝试使用低耦合的设计模式,如工厂模式,而是把很多面向过程的思路在三周内从头贯彻到尾。

    HW1中,要实现的功能不多,程序勉强还算能看。

    自HW2起,复杂度和耦合度似乎踏上了不归路。HW2是我的第一次代码重构,在Poly中用大正则取出各项后创建Term对象保存,进一步取出项中各因子的组成要素后再存入对应Type进行管理,最后Poly-Term-Type调用求导。从类中的方法可以看出,Poly与Term扮演了过分多的角色,尤其是后者几乎把本该属于Poly的化简功能、因子类的解析功能也都包办了,非常难以管理

    HW2虽然混乱不堪,但还算实现了预期目标,即求导+化简,而HW3终于让我吃到了糟糕的架构设计带来的苦头。如果沿用HW2的思路,可基本实现表达式树的构建,经过上一次强测和互测的bug修复,求导的正确性也不会有问题,但是难以进行优化。沿用之后,为了实现递归调用求导,因子类只能选择链表来管理嵌套表达式,这样一来,先前通过比对因子的“全名”进行输入输出化简的方法难以实现,除非冒着TLE的风险,先把链表遍历化简一遍。

    这时候,其实应该立即重构,把一切的起点,项的读入,彻底地换个血,一上来就将其化简,再交给Term,但是我却不想因此改变已经没有疏漏的求导方法,最终决定不再重构,放弃了性能分。

    二、 bug analysis

    HW1:输出时把求导前的系数当成求导后的系数,导致甚至没进入互测。

    HW2:获取因子过程指数为0时漏取、求导后因子系数为1时化简错误、化简输出时多输出*号。

    HW3:多冗余括号时的TLE。

    bug虽多,但是最能说明问题的来自HW2。其余的bug尚可归因于偶然性以及不属于本课程重点的算法问题,但HW2的bug有很大的必然性。通过分析其bug所处的类方法可以看出,它们的产生根源于Term类过于臃肿,功能太多,难以管理。“集大成者”Term几乎与除读入外的所有工作都有关系,处理的数据之复杂可想而知。把多个包含大量特判的方法集于一身,不出bug才令人意外。

    三、hack strategy

    1.理解程序。

    2.按照程序实现流程定位各部分的核心代码。

    3.手动构造数据测试各部分边界情况,发现bug时尝试修复,再重复进行步骤3直到完成所有部分。

    4.借助自动机生成数据进行多组测试。

    四、对重构的思考

    在后两次作业中,更好的思路应该是将创建项、创建因子、求导等行为抽象出来,引入更多的类。采用抽象工厂模式,为这些类提供不同的工厂,从而实现解耦,分而治之,如此程序才更具有层次感,方便管理和扩展。

    五、对比和心得体会

    善用一些设计模式才能够为程序带来层次感和组织感,实现易维护、易扩展、易复用、灵活性好的特点。

    从下一单元起,希望自己能够学会抽象,从更贴近问题本质的角度设计结构;不仅仅追求正确,要大胆尝试不同的设计思路,把学会更好地设计程序作为学习本课程的真正目标。

  • 相关阅读:
    从BATS交易所获取空头头寸
    用cython提升python的性能
    用Python编写的第一个回测程序
    Omi框架学习之旅
    Omi框架学习之旅
    AlloyTouch.js 源码 学习笔记及原理说明
    AlloyFinger.js 源码 学习笔记及原理说明
    Git 学习笔记
    从数组中每次取一个不同的数组成员 getRandomItem(arr)
    move.js 源码 学习笔记
  • 原文地址:https://www.cnblogs.com/edogawaai/p/12525198.html
Copyright © 2020-2023  润新知