OO第一单元总结

OO第一单元总结

基于度量的程序结构分析

  • Homework 1

    • 代码度量

    • UML类图

    • 优缺点分析

      • 优点:
        • ①结构清晰,模块与模块之间耦合度较小。将整个表达式拆括号过程分为预处理、解析表达式、计算表达式、输出结果这四个模块,main函数仅负责流程控制,其他模块负责功能的具体实现,模块间仅传递一个字符串或一个哈希表,符合高内聚低耦合的设计原则。
        • ②采用递归下降的解析方式,可以处理嵌套括号,适合迭代。
      • 缺点:
        • ①未用正则表达式处理字符串,导致识别每一项的代码十分冗长。
        • ②拆括号时“将符号拆入括号内每一项”的问题没有想清楚(但是稀里糊涂地实现了),导致第一次作业debug和第二次作业迭代的时候走了很多弯路。
        • Item类有并不属于它的属性。这个类本来是记录每一项的具体信息的,但是为了计算和合并同类项方便在其中加入了itemToSplit这个List来在一项中储存不能合并的n个项,非常丑陋。
  • Homework 2

    • 代码度量

    • UML类图

    • 优缺点分析

      • 优点:
        • ①采用递归下降的解析方式、递归处理sum函数的子串,可以处理嵌套括号和嵌套调用函数,适合迭代。
      • 缺点:
        • ①对新增加的自定义函数未引入新的模块单独处理,导致main函数既包括了流程控制、又包括了部分功能的具体实现,结构比较混乱
        • ②Item类有并不属于它的属性这个问题并没有解决,甚至为了计算三角函数又引入了记录三角函数的List,让它变得更丑陋了。现在Item类变成了一个缝合怪,但是因为计算和合并同类项非常方便,所以直到最后我都没有重构。(现在想来更好的实现方式是把多项式项和三角函数项分别单独建类,且都作为Item的子类,Item中保存itemToSplit这个List来在一项中储存不能合并的n个项。并且这样做也可以把合并同类项部分和calculate模块解耦)。
  • Homework 3

    • 代码度量

    • UML类图

    • 优缺点分析

      • 优点:
        • ①模块与模块之间耦合度较小。main函数仅负责流程控制,其他模块负责功能的具体实现,模块间仅传递一个字符串或一个哈希表,符合高内聚低耦合的设计原则。
        • ②进行了sin(0)、cos(0)、平方和优化。
      • 缺点:
        • ①由于Item类的设计不好,导致合并同类项和计算无法解耦,只能都放在Calculate里,Calculate类极其冗长,而且功能实现和优化部分混在一起的架构也不好。
        • ②对sin/cos括号内的计算的设计想当然地沿用了第二次的思路,然而第二次的思路本质只能计算sin/cos嵌套括号最里层括号内的内容,与第三次作业不完全相同,导致第三次出现惊天大bug,强测寄的很惨。
        • ③sin(0)、cos(0)、平方和优化分别放在了项的识别和计算过程里,功能实现和优化部分混在一起的架构不够好

Bug分析

  • 第一次作业没有出现bug。第二次作业有一个bug:计算三角函数合并同类项的部分,判断两三角函数项是否完全相等少了判断三角函数因子项数相等的条件。第三次作业有三个bug:①计算带三角函数嵌套括号的设计有问题导致三角函数内多层嵌套时只能计算最里层;②由于sin/cos括号内因子是表达式的情况要加括号的问题format error;③sum函数的上下限未考虑到超出int的情况。
  • 总结一下所有出bug的地方,大致分为两类:设计上的考虑不周未仔细阅读指导书
  • 对于一些设计上的考虑不周,我都是被别人发现bug以后再回来看,发现原来自己错的地方那么显然。但我觉得这些看似很简单“只要再仔细一点就能想到”的地方我却始终没有检查出来,一个最重要的原因是我在写每个模块之前都只想了”这个模块大致要干什么“,整个模块的实现过程完全是想到哪里写到哪里,完全没有提前设计、也没有写完以后复盘。而由于bug十分细节,自己没有针对性地构造的数据也很大程度上测不出来。避免这种bug最好的方法应该是:在写完一个模块、并且脑子清醒的时候,再读一遍自己的代码,复盘是否将所有可能情况全覆盖了(要注意仔细读指导书考虑所有可能情况)。还有就是多做测试,仔细想想输入的所有可能的组合形式(最好的办法当然是自动化测试,但是本菜狗目前不会……)。当然以上这两条最大的困难就是克服自己的懒惰……
  • 对于因为没有仔细阅读指导书导致的bug,这次错的实在是痛彻心扉,我决定以后一定要克服懒惰仔细看指导书,尤其是形式化表述的部分。
  • 我的作业中出现了bug的方法和未出现bug的方法在代码行和圈复杂度上并无明显差异。这个结果似乎有违直觉,因为一般出现bug的方法在代码行和圈复杂度上会更高。我的作业会呈现这样的结果,一方面因为bug有一半锅在format error,一方面因为我的很多没有出bug的方法也非常复杂,有的甚至嵌套了五六层if,而出了bug的方法因为本身设计思路的问题反而并不复杂。事实证明bug和代码行、圈复杂度并无明显的直接联系,更重要的是多做测试和复盘检查。但是毫无疑问,更简洁清晰的代码出bug的概率会更低,毕竟测试也很难做到全覆盖,且复杂的代码更难迭代和看懂,所以设计的时候一定要考虑到代码的复杂性,对过于复杂的方法进行拆分

Hack策略分析

我找别人的bug主要通过以下两种方式:①用自己写程序和自己测试的时候出现的bug去测别人。②看群里同学们的讨论和分享。这种方式一般一次能hack到2-3个人,因为大部分时候大家的bug是共通的。时间和能力所限并未阅读其他人代码,所以未能结合被测代码的设计结构来设计测试用例。

架构设计体验

  • 第一次作业我采用了training中给出的递归下降解析的方法,此架构能够处理嵌套括号,非常适合迭代,所以我即使在“把符号拆进括号内每一项”这个问题上遇到了很多困难也一直没有放弃。我在training给出的框架基础上补全了预处理、解析、计算和输出部分,形成了结构比较清晰的第一次作业。第二次作业可以在我第一次作业的基础上迭代,我在解析部分加入了sin/cos因子,在解析之前加入了对自定义函数和sum函数的预处理(字符串替换成正常多项式)。第三次作业由于第二次作业太适合迭代了,几乎没有什么改动,只是把第二次作业中自定义函数和sum函数的预处理部分变成了递归函数,使之可以处理递归调用的情况。
  • 体验就是,第一次作业的架构设计非常重要,设计好了后面都会轻松,设计的不好迟早要重构。最重要的事情是不要偷懒,觉得难的部分往往绕不开,不如一开始就努力想办法把难点解决

心得体会

第一单元的作业总的来说完成的比较顺利,虽然结果有许多不尽如人意的地方,但和计组的折磨和痛苦比起来这些都是小问题了……有几点特别深刻的经验和教训:①仔细阅读指导书!!仔细阅读指导书!!仔细阅读指导书!!第二次作业因为没仔细读指导书少看了要求导致wa一个点周五周六两天都没有解决,挣扎的很痛苦,差点交不上;但也许就是因为第二次作业不幸中的万幸交上了,第三次作业又没仔细看指导书,导致强测寄的很惨,太心痛了。②中测发现的小bug背后可能隐藏着惊天大bug!有些小bug修好了只是修补了表皮,一定要慎重地考虑一下背后的设计问题!!不要对中测掉以轻心,现在看我强测的设计上的问题有一部分在中测就暴露过了,只是我没有看透本质,掩耳盗铃。③不要懒惰!虽然这个很难,但希望我每次犯懒的时候都能想起此刻寄强测时的心痛,多构造数据做测试。

posted @ 2022-03-25 11:50  Siazxyyy  阅读(61)  评论(1编辑  收藏  举报