OO第四单元及课程整体回顾总结

OO第四单元及课程整体回顾总结

前言

终于顺利地完成了第四单元的迭代开发,为OO课下作业画上句号。在一学期的面向对象学习中,笔者的代码能力得到巨大的提升,也收获了许多面向对象领域的知识。在此做一次总结。

一、第四单元架构总结

第四单元的作业是根据UML语言规范,对mdj文件解析,实现对查询指令的反馈。其中,第三次作业还要求对mdj文件进行一定范围的模型有效性检查。

本人在实现本单元作业时,实现了以下类:

  • MyImplementation类:继承官方包提供的UserApi接口,UMLElement元素列表和查询指令的入口;
  • MyParser类:负责解析UmlElement元素,建立元素之间的连接关系。对于部分元素,使用下方MyUmlClass等类再进行一次封装。
  • MyUmlClass、MyUmlFinalState等类:为了避免MyParser类过于臃肿,将UmlClass、UmlFinalState等众多类再进行了一次封装,使它们能自行完成一些指令的查询任务。

本人实现的所有类如下图所示:

代码的执行过程如下:

  1. 创建MyImplementation类对象,该类的构造函数会创建一个MyParser类对象,并将UmlElement[]传递给MyParser类的构造函数;。
  2. MyParser类的构造函数对UmlElement[]列表中的元素分类到各个元素的ArrayList或HashMap中。在保存完毕后,调用自身的解析函数parse()。
  3. MyParser类的parse函数会按一定的顺序解析各个元素,例如,会先解析UmlOperation,再解析MyUmlClass,这样MyUmlClass在解析时,其已经获得了自身包含的所有UmlOperation的信息。
  4. MyImplementation类的各个checkForUml00X方法被调用,调用MyParser类的同名方法进行模型有效性检查。
  5. 开始执行查询指令,MyImplementation类在受到查询指令后,调用MyParser类的同名方法进行模型有效性检查。

就迭代开发方面,从第一次作业到第二次作业,主要是建立了MyUmlLifeline等新类,用于处理顺序图、状态图的一些新指令,并扩充了MyParser类的解析函数。从第二次作业到第三次作业,主要扩充了MyParser类的模型有效性检查函数,从某种程度来说,模型有效性检查和执行指令有相似之处,都是通过MyParser类调用其他元素类的方法,返回查询结果。

二、课程整体总结

(一)架构设计思维与OO方法的历练

平心而论,面向对象课程给我带来的最大的收获就是架构设计的锻炼,我认为这给我的开发能力带来了极大的提高。除此之外,我也学会了一些具体的OO方法。

其实本人上学期就学习了Java课,并且在当时完成了一个2000行左右的Java大作业——一个平面射击类游戏。当我现在在回去看当时写的代码,只能佩服当时的自己能在那种残破的架构下写完代码——所有的代码都在一个java文件下,毫无代码风格可言,而最糟糕的是,类与类的关系错杂混乱,全代码只使用了极少的继承,而大量的关联关系散布在各个类之间。这在现在的我看来是不可理喻的,自己也必然不会在写出这样的代码。如果说这样的改变来源于什么,就是本学期面向对象的四次单元训练。

第一单元中,我的架构能力得到巨大的提高。在pre训练中感受到继承、多态等面向对象特性的精妙后,我在第一次作业小试牛刀,尝试使用这些特性。加之第一单元训练,本就是本着提高学生的层次化设计能力,我在解析表达式时采用的递归下降方法也需要精妙的架构设计。最终,虽然在设计和开发上我花了特别多的时间,但最终也对架构设计有了全新的理解。

第二单元中,我体会到差的架构带来的巨大代价。本单元中,我初次接触多线程,尽管收获了许多OO的新知识,但理解和时间多线程知识,带来的是架构设计时间上的压缩。从第二单元第二次作业开始,我的代码架构就已经开始畸形,直接的一个表现是,出现了大量重复的代码。而到第三次作业,架构就已经完全无法适应作业要求,无论是迭代开发还是debug都令人头疼。本单元的作业让我不得不重新重视接下来两个单元的架构设计。

第三单元中,我学习了规格化设计,学会了读写JML规格语言,并在JML的指导下完成作业。这一单元我学会了新的OO方法,并且初次感受到为了完成大规模的代码,为了更好地多人合作,开发人员需要寻求一些新的方法。此外,通过本单元,我也重新复习了之前学过的一些图论算法,巩固了以前的知识。

第四单元中,我学习了UML语言,并通过解析mdj文件,提高了对UML语言的理解。本单元同样需要一些简单的架构设计。我吸取了第二单元的教训,事先经过了慎重且详尽的架构设计。不过本单元对架构也没有太高的要求,因此在三次作业的迭代开发中也没有遇到太大的困难。

总结来说,四次单元作业,我提高了架构设计能力,也掌握了许多具体的OO方法。

(二)测试能力的提升

OO课让我体会到测试能力的重要性。过去,在学习C语言和数据结构的时候,我的目标往往只是通过测试数据点,因此当本学期课程组只在代码完成阶段提供弱测和中测数据,且设计了激烈的互测环节时,我一开始确实没有适应。

幸好,我在第一单元第一次作业中得到同学的提醒,早早地开始尝试搭建评测机。在后来的众多作业中,也得到了同学在测试方面的帮助。因此,我在强测和互测环节也还取得了不错的成绩。

在测试方面,总结来说,本学期我得到了如下经验或教训:

  1. 测试永远要针对代码需求,而不是针对代码实现。搭建评测机时,我有时会不自觉地代入自己代码实现上的想法,这时往往反而不能达到测试的目的。例如在第一单元第一次作业中,我就没有严格按照形式化语言描述来搭评测机,导致最后评测机的效果大打折扣。
  2. 当面对大规模数据时,随机测试会面对巨大的瓶颈。这条经验主要来自第三单元。第三单元中,评测机要处理的变量包括指令种类,指令的众多组成元素,甚至包括各个元素之间的关系。如此大的数据空间,使得随机生成的测试数据,效率变得非常低。我想,这可能也是当前测试领域所面对的问题。
  3. 重点构造边界数据,能带来巨大的效率提高。针对以上第二点,个人在实践中的解决方法是,更多地构造边界数据。例如,第一单元第一次作业中,数字常量不应该在一定范围内纯随机,而可以针对性地设计数字常量池,包含一定比例的大于long的数,大于int的数,小于int的数,也包括0这样比较特殊的数字。通过对边界数据的强调,可以提高评测效率。
(三)课程收获

总结来说,我将自己的课程收获列举如下:

  1. 架构设计能力的巨大锻炼。
  2. 多线程、规格化设计、UML语言等知识的掌握。
  3. 测试能力的提升。
  4. 阅读需求、理解需求、实现需求的能力提升。每一次单元作业中,阅读指导书,思考架构,程序开发,就是一次对需求从理解到实现的过程。这也是我在本学期OO作业中的收获。
  5. 抗压能力的提升。尤其在第二单元,当面对巨大的任务量时,我学会了沉下心慢慢思考,找到破局之道。
  6. 总结归纳能力的提升。在强测不过、互测被hack等多种情况下,总结错误原因,避免在下次继续犯错的能力。
  7. 查阅资料的能力提升。在完成作业中,有许多地方需要查阅资料。这其中也包括搭建评测机等其他环节。我至今仍记得自己在第一次用python搭评测机时,为了理解subprocess的用法,上网查资料的经历。
(四)对课程的建议
  1. 感觉课程的讨论区可以再优化一下。就每次作业的“指导书问题反馈专用贴”而言,大家的提问和回复是相互交杂的,不太能看到每个提问的答案。或许可以设计成这样的模式:针对某个提问的回复直接置于该提问下,类似于微信朋友圈评论一样的形式?
  2. 第三单元中,本人感觉不太能把握住时间复杂度的要求。目前,第三单元的指导书提供了各个指令的次数限制,并提供了具体的时间要求(2s, 10s等)。但对于本人来说依然不太能具体的明白代码需要优化到什么程度。或许课程组可以考虑为大家提供一些参考,例如O(n^2)复杂度的函数执行1000次的大约用时,或者为大家提供一些自行查阅和理解的资料?
  3. 第四单元的指导书pdf指导手册感觉还可以再完善一下。我个人在完成第四单元第一次作业时,一开始很难理解自己需要完成什么任务。由于第四单元提供了许多需要阅读的官方代码,一时会很难上手。或许可以考虑在指导书中加入对第四单元官方代码的介绍?此外,第四单元指导手册,个人感觉有些乱,可以考虑整理完善。
posted @ 2022-06-29 15:43  深夜竞走的KFC  阅读(73)  评论(1编辑  收藏  举报