Object-Oriented Programming Summary Ⅰ

 

 

17373492  Beihang University


Part 0: 前言

使人闻风丧胆的OO仍是来了。并无像名字的外表同样可爱,简直就是恶魔。java

疯狂压榨OS的时间,周末没法休息,互测狼人机制正则表达式

虽然网上骂声不少,就算改进到9012年仍是有不少不足的地方,但和往年相比,已经有很大进步,也更加人性化了,咱们并不能力求在咱们这一届作到完美,这毕竟是一个长期长期长期长期又漫长的过程。既来之,则安之,既然没法改变规则,就让本身适应规则吧。架构

 

Part 1: 量度分析

接下来将细分开每个板块来对我本身的三次做业来进行分析ide

DesigniteJava

DesigniteJava是一款专门分析代码质量的静态评估工具,而且识别潜在的质量问题。它会检查代码的架构,设计和代码的异味而且以csv的格式给出详细的度量分析。函数

对与分析Java这种面对对象的语言,咱们此次主要看这几个参数:工具

  1. CC 圈复杂度性能

    用来衡量一个模块断定结构的复杂程度,圈复杂度越大说明程序代码质量低,难以测试和维护学习

  2. LCOM 方法的内聚缺少度 值越大说明类内聚合越小测试

  3. FANIN 类的扇入 扇入表示调用该模块的上级模块的个数,扇入越大,表示该模块的复用性好。优化

  4. FANOUT 类的扇出 扇出表示该模块的直接调用的下级模块的个数,扇出大代表模块内复杂度高,但扇出太小也很差。

    总结就是,一个好的JAVA代码,设计要求是高内聚低耦合的,因此LCOM值要小,FANIN的值要大,FANOUT值合理。

     

    那么用这个方法看三次的度量结果:

     

    第一次做业:

第二次做业:

第三次做业:

 

能够发现,在Main函数中咱们的圈复杂度都是相对较高的,这是由于我在Main中放了存放和预处理字符串的代码,这致使圈复杂度增高,并且确实大量的正则表达式和字符串替换难之后续阅读和维护,这是毋庸置疑的。看了其余同窗的优秀代码,好比17373331的代码,Main中几乎没有什么实际的执行代码,只是在调用其余方法和处理异常,看优秀的代码给个人感受就是很是清晰,在主函数中就明确告诉我了这个project是在什么的,合理的类的命名,简单易懂的返回值设定和处理异常的语句,符合OOP的设计。

果真,没有对比就没有伤害:17373331的静态分析:

 明显能够看出参数饱满了不少,不像我生成的几乎都是0,较小的LCOM和较大的FANIN和合理的FANOUT,果真花花的代码能被称做标杆范文。
 
此外,能够看到个人代码分析后的FANIN是几乎没有的,说明个人代码的复用效率低下,可能存在不少重复的代码,反观个人代码确实在这几回做业中,确实有不少服用的代码,就好比字符串为了防止被查WF,反复用正则表达式检查变换几回,甚至用上了 while (matcher.find())这样的循环查找,不只复用率低下,其实代码的执行效率也很是低下。

  反思本身的代码质量,几乎惨不忍睹,甚至感受用来查c等面对过程的语言获得的结果也相差无几,主要是如下几点缘由:
  1. 阅读面对对象的代码太少,学习了理论可是没法本身亲手时间,可能具有了阅读不一样的代码说出是否是符合面对对象的设计,可是本身却没法写出。

  2. 对质量的盲目追求。在分数的利益驱动下,天然地用面对过程的语言,也就是本身熟悉的语言来处理字符串,这样虽然代码不是很好看,甚至在第三次做业中为了判断各类WF状况而写了冗杂的正则表达式查询代码,致使主函数内方法函数超60行,代码风格质量严重下降,这时又只能经过分开创建不一样的方法来分担正则式的长度,恶性循环致使风格逐渐降低,可是分数能够很好,别人几乎不能攻击个人WF,这也是对本身的代码风格和分数之间的trade-off之间,分数占了上风吧。

  3. 尚未造成剥离抽象层的思惟,像zsa学长在讨论区的接口讲解很是清晰,举出了生动的例子——手机的充电接口来让咱们理解。 可是老是在本身构思的时候就没法剥离出sin cos 和x 和constant 之间的共性特征和共性方法,因此也不多使用继承或者借口了,在最后一次的做业中强制要求使用后才尝试用接口的方法来解决求导的问题。

接下来查看本身的UML图,由idea自动生成:

第二次做业UML



第三次做业UML

第一次做业彷佛没法生成UML,多是由于太面向过程了一点,但我还能够看到第二次和第三次的,可是要我评价本身的类图,我十分羞愧,由于这彻底是一个没有上过OO理论课的人都能写出来的东西,因此我大概讲一下个人类图在写代码时的构造吧:

在第二次的代码中我才用了四元数的方式,因此本身构建了两个class,分别是Trig 三元组储存x 和 sin 和 cos,还有Term 四元数在三元数的基础上增长了前面的常数项,由这两个class咱们就能够对相同的相进行合并。而且尝试了多态的方法;在第三次的代码中采用了接口的方式,对全部项的求导进行了归一化,可是其实能够更加优化,那就是将全部的项归并到抽象类中,由于他们都有共同的属性好比内部的表达式(指sin和cos内部的值)还有幂次都是共通的,用抽象类的方法能够将他们更加内聚在一块儿,因此我也打算从新写一遍第三次的代码了,固然是创建在阅读第二次优秀的代码基础之上。

在第三次做业中,我也对static和final有了更进一步的了解。以前看到java的代码中不少的static因此没有融入本身的思考盲目static,这直接致使我第二次做业开始,开的类多了以后出现致命的错误,建立多个对象以后共同修改一个属性,致使了大片的错误输出,因此说仍是实践出真知。

Part 2: bug分析

第一次做业:

第一次做业比较简单,固然本身用面对过程的语言作因此没有出什么问题,最后是数据点全过+0hacked,可是固然还有美中不足的地方,那就是性能分没有拿到满分,具体在于本身运用HashMap的方式存储结果,查询不到HashMap如何查找到特定value的值,即正数的值放到第一位,因此最后性能分未满,可是若是如今要我再交的话,我会利用先存进ArrayList的形式来作一个简单的排序,从而将正项第一个输出。

第二次做业:

第二次做业在强测中出了一个BUG,致使被分配到了C组中去,由于本身优化太过于匆忙,疏忽了HashMap在puts以前要先检查是否存在,致使相同的Key值出现了覆盖Value的状况,最后失分。其实本身写了一个专门puts进HashMap的方法,在方法中检查了Key值并进行合并,可是因为是ddl前的早上优化因此没有进行太多的测试,过了弱测和中测就没有多想,这个案例说明 侥幸心理 是万万不可取的。

在互测屋中还被发现了一个特殊的bug,在输入以运算符结尾的时候我不能判断出格式错误,致使被人狂刀,这也是和本身的测试策略有关,本身在自测的过程当中偏向于对正确性进行检验,而忽略了错误形式的表达式的构建,致使失分。

第三次做业:

吸收了第二次做业被WF杀害的经验教训以后,几乎最后一天都在对格式判断进行改动,可是没有注意到助教的置顶帖中已经说明移除了WF的数据,有一点时间没有用到刀刃上的感受,甚至有点把本身给误伤了。过多的特殊WF状况的判断致使本身对代码的结构已经没法理解,结果在强测中对正确的输入报了WF,痛失去一个强测点。此外,对括号内的处理也不够仔细,忽略了幂次也能带有负号的问题,致使表达式提取出现问题,结果丢分。

 

在第一单元最后一次的研讨课上,有位同窗给予了咱们一个开始工程的思路——先构建数据集(测试集),再下手打代码,起到打代码的时候有的放矢的高效。开始的时候我是有点不理解的,可是在反思本身的做业的过程当中,发现第三次做业中我所犯下的错误彻底是能够由一开始构建一个较为完备的测试集而规避的,并且纪老师说在后续的工程化代码中,提早构造测试集是一种很是有效防止严重漏洞的手段,因此我也考虑在重写第三次做业的时候也尝试这种方式。

 

Part 3: hack

对于查找别人的漏洞的方式,主要在于如下几点:

  1. 本身在打代码的时候,测试本身的代码时所出错的数据点都一一保留,这应该是算弱测。

  2. 寻找特殊的表达式的特征,具体多是x-x或者多个+-号的形式。

  3. py或者java自动生成代码加上mma的带入测试。

  4. 寻找同窗进行求助,每一个人对同一问题的思考角度不一样,hack别人的点通常有很大区别,因此是一个补全的很好的策略。

 

Part 4:重构的说明

重构其实不是一件丢人的事情,自从上学期计组以来,发现其实解决本身bug的最好最快的方式就是重构。重构能够帮助咱们在原有的基础上进行改善,一方面验证咱们对现有知识体系的更加深层的理解是否正确,另外一方面也是对将来增添功能时候提供一种方便。在初学的阶段,我认为重构代码时很是常见的,也是一种高效的学习方式,虽然时间会花费不少,因此在第二次做业中我就采起了重构的方式,改掉了原有的面向过程的写法,采用了初级入门的面向对象,而且在第三次做业中也复用了第二次做业的体系逻辑,虽然增添删改了许多内容但其实也减轻了我挺大的工做量的。

 

以上即是本人对于前三次OO做业的博客总结,后续可能会贴上本身第二次做业甚至第三次做业的优化的方法的思考。

相关文章
相关标签/搜索