OO第四单元总结

OO第四单元总结

架构设计

        在本单元的四次作业中,我们主要围绕着UML模型开展。和之前几次作业不太相同的是,前面的单元难点在于:如何根据指导书或者JML规格,写出合理高效的代码。但是这一单元,难点在于:看懂指导书。可以说,在这个单元中,最核心最关键的任务就是正确理解UML的各种图(类图、顺序图、状态图等),然后看懂指导书。总的而言,这一单元让我们从另一个视角看待面向这回事,我也在学习了这一单元后,终于明白了每次博客都要画的类图是什么意思

第十三次作业

        在次作业中,主要的任务就是解析UML类图,正确处理其中的关联、继承、实现、类、接口等等UML对象。然后要实现一些基本的查询功能,这些查询比较繁琐,因为有的要考虑继承实现,有的不考虑继承实现,在做的时候确实要仔细阅读指导书。

        我在编程的时候,非常清楚地感觉到,这次作业和上课的内容结合非常紧密,很多的UMLElement都在课程中有详细的讲解。

        在具体的实现上,我首先建立了ClassGraph这一个类,这样一来,就把它要求补全的interaction完全变成了交互界面。然后为了一定程度上保证查询的速度,我又建立了ClassInfo、InterInfo来记录类和接口的缓存结果。类图如下:

第十四次作业

        这次作业主要是在上次UML类图解析的基础上,加上了状态图和顺序图,增加了若干个UmlElement。这次作业的实现,也是建立在正确清晰地理解UML模型相关概念的基础上的。由于我上次扩展性做的比较好。所以这次的作业,我只是新增了保存state machine的类,lifeline的类和state的类,然后在graph.java实现和指导书一一对应的函数。

        和上次相似的是,我的general interaction也只是做了一个交互界面使用,没有复杂的功能,而是调用了graph相应的函数接口,这样可以看的清晰很多。

        可以说,这次作业的概念和上次比起来更加复杂,消息的传递,状态的转移等元素也更难描述。但是有了上一次作业的练习,也不算特别困难。类图如下:

第十五次作业

        在这次作业中,所有的工作就是进行一些简单的错误检查。可能是由于我前两次的架构没有大的问题,在这次作业中,我没有新加任何文件,直接在graph的层面进行相应的检查就可以了。

        在所有的检查中,可能最困难的一个就是检查是否循环继承或者重复继承。在处理重复继承的问题上,我的方法是建立一个list一个set,递归地加入继承的对象,如果最后list和set的长度相同,说明没有重复;反之有重复。而在处理循环继承的问题上,由于我之前缓存的内容就有一个类的所有父类,所以这里只需判断他自己在不在父类集合中。这个操作是相对来说非常简单的。

        类图如下:

BUG分析及反思

        在这三次作业中,我出现了一个BUG,就是在某些情况下会产生超时的问题。细究原因,是因为我在添加一个属性的时候,如果这个类有子类,那么相当于子类也具有了这个属性,需要相应更新。这个问题对于类的单继承而言是不成问题的,但是对于接口,就可能出现重复更新的问题。这种重复更新不会导致错误,但是会让时间白白浪费。我在调试的时候,发现递归的次数(不是深度)甚至让一个int类型的变量溢出了,远超我的预料。

        但是我觉得这三次作业,我的架构设计还是比较好的,没有出现重构或者事后烦恼的问题。

架构设计及OO方法理解的演进

第一单元

        第一单元是求导的单元,也是我感到最为痛苦的一个单元。在这个单元中,我感觉到我每次在设计的时候,都没有事先谋划好,进行统一的安排。而且在这个单元中,我对类的分析和构造非常有问题。很多的缺陷都是在实现的时候才发现,这就导致我的代码只能在修修补补中艰难前行,虽然是完成了,但是过程非常艰辛。最糟糕的是,这种修修补补的破烂实在顶不住下一次作业的开启。所以我几乎在每次新的指导书发下来时,都只能绝望地开始重构。但是在经历了这个单元的折磨后,我也对如何构建好的框架有了一点心得。

第二单元

        第二单元是电梯的单元,在这个单元中,我们主要是对多线程进行了一定的实践。在这个单元中,架构可复杂可简单。如果从简单而言,这次的结构实际上已经有了很好的范例,也就是生产者-消费者模型;而如果从复杂的角度而言,如何实现好的调度,如何在尽可能少的地方加锁,就变得尤为关键。

        在指导书之中,有一句话我觉得说的非常正确:不要为了追求性能而忽视了正确性。尤其在我们这种时间相对紧迫的作业中,我觉得尤其是这样。所以在设计的时候,一定要坚固正确性和速度,这样才算是好的设计。

第三单元

        第三单元是JML的单元,在这个单元中,我们根据JML规格,实现严格的相关函数。在一开始做这个的时候,我很疑惑:这样还有什么我可以设计的地方吗?不是只需要做填空题就行了吗?但是,在慢慢的实现过程中,我逐渐明白:设计和实现应该是分开的,JML只是帮助我们确定了设计,但是具体的算法实现需要我们自己思考,自己构建合理的结构。我想,这是我在这一个单元最大的收获。

第四单元

        第四单元也就是UML的单元。在这个单元中,我感到我对架构设计的理解有所进步,三次作业都没有对之前的代码加以修改,直接新加即可。在这一单元中,我们也学习了UML这个工具,通过它我们可以对一直抽象难言的所谓架构设计进行非常直观的描述。这点我也觉得非常有意义。

测试理解与实践的演进

        事实上,测试是一个大问题。在程序的编写和开发中,保证程序的正确性非常重要,也非常困难。而在本学期的学习中,我逐步在测试上有了自己的心得体会,能够测试出许多的bug了。在一开始的时候,面对测试,我的内心想法是:“这怎么测嘛?”“瞎测真能测出来?”“我得手写1000个样例?”“这个导数我都不会求,我的程序会求吗?”这些问题总的来说就是分成了几个层面,也就是:1、如何生成样例?(自动or手动)2、如何检验结果的正确性?3、如何确保数据的覆盖性?

        在四个单元中,我所有在测试方面的尝试也都是围绕着上述三点展开的。第一单元的测试,我主要是手动胡乱生成的数据,用sympy检验。这种检验事实上效果不好,虽然包含了一部分特殊边界,但是覆盖性差,而且手写真的很麻烦。在第二单元中,我则使用了自动测评的方法。自动生成测试样例、根据指导书的规则自动检查输出合理性,这也就使得我在第二单元没有出现WA的问题,可是这样真的能保证边界的全覆盖吗?这是存疑的。而在第三单元中,我们引入了JUNIT测试法,通过这个,我学会了有针对性地对边界进行测试,能够生成一些高质量的测试数据(而不是大量轰炸)。在以上三个单元的训练之下,第四单元我明显感到测试变得轻松容易了很多。但是由于没考虑到时间问题,tle了一个点,这是应当注意的。

课程收获

        通过这门课的学习,我终于有了更强的代码能力。之前我或许最长的记录就是编写几百行的代码,它的功能比较单一,调用关系也不复杂。但是通过这一个学期的学习,我们编写了好几个千行级别的代码,也算是对如何构建规模比较大的程序有了一点自己的心得,我觉得这是非常重要的。

        在课程中,我也深刻意识到了面向对象思想的重要性,可以对一些问题进行自己的分析。之前我一直保留着那种面向过程的思维,但现在我愈发感到:面向对象的思维是构建大型程序的必备工具,这让我获益很多。

        还有一样东西,就是checkstyle。这个小插件在我们一开始接触的时候,曾经让我非常厌烦。但是现在,我也意识到,良好的代码风格可以大幅度增加程序的可读性和美观性。我觉得,现在我就算把那个插件卸载掉,我也会自觉地遵守checkstyle了。

改进建议

        1、现在每一单元一共四周,课堂实验时安排在第1、3周。这样会导致第一个星期还没有领会要点的时候就得做实验了,学习曲线比较陡。或许可以把实验放在第2、4周会更利于同学们掌握。

        2、感觉实验课可以有一些课后的反馈,让我们大概知道那道题到底应该怎么做。毕竟那些题我们已经思考了很久,如果不知道答案总觉得稀里糊涂的。

        3、多线程问题或许可以给多点提示或者预习,刚一上手难度有点大。

线上学习体会

        感觉总体而言,oo课似乎线上线下差别不大。(也可能是因为我没参加过线下的oo)我感觉,主要的课下测试没有变、讨论区的主要交流方式也没有变,应该整体区别不大吧。

        但其实区别还是有一点咯。就比如我发现,通过微信群聊的方式,课堂的互动变得更加频繁了,更多的人愿意把自己的想法拿出来和大家一起交流,这是非常好的。当然啦,这种交流可能也会遇到一些障碍。就比如当老师讲到思考题1的时候,有的同学可能正在思考2,也有的同学可能还在看基础知识,这种不同步可能会使讨论群有时候鸦雀无声。这可能就是老师和学生不能进行一致性同步造成的后果吧。

        而且通过这种录播的形式,同学们没有消化的知识点可以通过反复播放的方法反复学习,直到听懂为止。事实上,我在第四单元学习UmlElement的时候就是采用了这样的学习方式,这才对相关的知识点有了更加清楚的认识。

        总体来说,虽然这学期我们采用了线上教学的方式,但是由于老师和助教们的辛勤付出,我感觉体验很好!!(完结撒花)

原文地址:https://www.cnblogs.com/kzxzvbk/p/13154534.html