北航OO第四单元(UML图解析)&课程总结博客

第四单元(UML图解析)&课程总结博客

第四单元要求我们对UML图进行解析,通过得到的UML元素构建起自己的UML图结构,接收到来的指令对UML图进行查询。庆幸的是课程组已经给我们提供好了相应的解析器和输入输出接口,我们只需要完成构建图结构的过程和接口中需要完成的相应查询方法即可,总体来说难度不算很大。这个单元取消了互测,每天都是平安夜的感觉真好( ̄︶ ̄*\))。这也是最后OO课程的最后一个单元啦,完结撒花~

一、本单元作业架构设计

这个单元的架构设计是我在四个单元中最满意的一次架构设计,从本单元第一次作业建立好架构后,之后的两次作业都没有在整体架构上进行太多的改动,只是对类、存储内容和方法进行了增量开发,就基本上完成了作业的要求。

第十三次作业

这一次作业主要是对UML类图进行解析。这一次作业是在基物实验考试的那一周布置的,最后只留了一天的时间来完成这一次的作业,说实话比较极限,所以当时是从功能入手来建构的架构。之后再根据性能和可扩展性进行一定的修改。

这一次的作业主要是查询UML类图中:

  • 类(Class)和接口(Interface)相关:类的个数、类的相连关系、类实现的接口、类的顶级父类
  • 属性(Attribute)相关:类的属性个数、类属性可见性、类属性类型、是否满足信息隐藏原则(可见性均为private)
  • 操作(Operation)相关:类操作个数、类操作可见性、类操作参数类型

根据这一点,我抽象出应该构建的类有:类MyClass、接口MyInterface、属性(UmlAttribute已经够用)、操作MyOperation等。然后再构建类与类之间的协作关系,这里根据经验我选择使用树形结构:在代码层级上,各个类进行组合和依赖实现树形结构;在数据层级上,MyClassMyInterface等之间实现树形结构。每个类中配备相应的查询方法和数据结构,交互类中一层层向下调用查询即可。为了满足性能需要,建立了相应的缓冲。考虑到可扩展性,我将类图有关的所有数据和方法都封装在MyUmlClassTree中,这样在之后扩展其他图功能时,可以降低各个类之间的耦合。

顺便一提,由于输入的元素顺序是不定的,数据存储的方便,在交互类的构造器中人为地控制了输入Tree的元素的顺序。

这样构建出来的架构出乎我意外的还不错,之后的作业架构会展开来说。

第十四次作业

如我上一次所料,这一次作业增加了对顺序图和状态图的解析。本来我已经做了对上次代码进行重构的心理建设,但这次似乎不需要。在上一次作业的基础上,仍然依据之前的思路,我增加了:

  • 状态图:UmlStateMachineTree,状态机MyStateMachine,状态MyState,状态转移Mytransition
  • 顺序图:UmlCollaborationTree,交互MyInteraction,生命线MyLifeline

依然按照上一次作业的方法,控制输入顺序,每个类配备相应的方法和数据结构即可。不过在这一次作业中,出现了上一次作业的遗留bug,即缓冲的设置和使用出现了一些问题。

可以清晰地看到三种图间的耦合性很低。

第十五次作业

这一次在之前的基础上,增加了查询前的错误检测,实际上类似于先进行一通自动查询,与之前的功能扩展没太大区别,只是适当地增加了耦合性。所以架构上基本没有变化。

这里有一点需要注意的是,之前的UmlAttribute只涉及到类种的属性,但现在在顺序图中也会存在UmlAttribute(且涉及到查询),所以存储时需要一定的区分。

二、四个单元中架构设计及OO方法理解的演进

一步步走过四个单元,我对“架构”的理解也是越来越明晰,也越来越明白架构的重要性。还记得之前老师说的,切忌拿到需求就直接动手写代码。现在回头看来真是如此,许多情况下,做好一个设计比完成一个代码更加重要。

第一单元,初步接触“面向对象”,我仿佛一个刚出生的孩子一样不断地试错、不断地适应,奠基了这个学期的整个学习。从头开始构建项目,从头开始建立测试,同时面临大段大段的指导书、面临恐怖的强测和残忍的互测,面临卷而又卷的性能分,第一单元我过的非常痛苦。第一单元我也面临了整个学期最大的一次代码重构,给我留下了很深的印象,从此开始重视“架构”的设计。OO是什么,这一单元给了我一个非常基础但非常明确的答案。

第二单元,是我学习到东西最多的一个单元。首先是多线程,看到指导书时我甚至连程序的基本输入输出该怎么进行都不知道。多线程究竟是个什么东西?这个问题从周三开始一直困扰到周日。必须感谢课程组设置的实验课,让我在绝望中有了一个模仿的对象,模仿中研究、学习,最终交上了一份有效的作业。其次是设计模式,在这个单元我接触到了很多设计模式,像策略模式、状态模式、工厂模式等等,有了这些作为支撑,架构设计显得容易不少,突然就觉得OO是一个接近自己的东西了。当然还学到了很多算法,这里就不说了。

第三单元,我以为轻松但实际上分数最低的一个单元。JML规格是个好东西,但需要使用它的人对自己的头脑时刻保持清醒。JML规格语言是设计和实现之间的桥梁,这意味着JML只关心程序的黑箱结果和正确性,不关心内部具体实现和性能。这一单元的架构基本都由课程组搭建,但我们仍需要根据性能要求对一些架构进行修改。这个单元似乎就与面向对象本身关系不大了。由于JML并不关心性能,如何优化算法成为了这一单元的重点。

第四单元,UML图解析完全扣紧了“面向对象”这一主题。无论是UML类图、顺序图还是状态图,都是平时面向对象设计时非常重要的工具,对它们进行解析分析,更加加深了我对面向对象这一概念的理解。架构设计在上一部分已经讲述,这里不再展开。

三、 四个单元中测试理解与实践的演进

“测试”这个过程真是贯穿整个OO的课程。在上OO课之前,我对测试的理解就是类似于“考试”,好像测试是程序员的一生之敌。但我逐渐发现并不是这么一回事(虽然我还是非常讨厌互测

在OO之前,我的认知中测试就是黑箱测试,即给出一个测试数据到程序,对比实际输出是否与期望输出一致。但测试的内涵远不止于此,测试还包括了白盒测试、性能测试、代码风格、内存测试等等,涵盖了各个方面。第一单元的测试是我比较熟悉的,即每个样例都有一个“标准答案”,但到了后面的单元,就不再存在什么“标准答案”了,或者说重点已经不在于“标准答案”了。例如第二单元输出并不重要,而是输出的时间;第三单元输出也有正确性,但对性能的要求更严格……到了后期,已经没有所谓的标准答案可以参照,测试更多的变成同学之间的“对拍”。

测试的主要方法,一是手动构造数据进行测试,这种方法最简单、最直接、也最能控制,但缺点就是数据量不大,测试不一定充分;二是进行黑箱测试,这一般依赖评测机自动构造数据、自动测试,能大量地进行测试,但搭建评测机并不简单;三是单元测试(白盒测试),这一点上JUnit是一个很好的工具,根据代码内容来进行测试。

四、课程收获

这一点在上面两个部分中穿插着讲述了,这里就不再单独说了。总的说,OO无论在代码编写上、程序设计上还是思想上都有很大的提升。

五、 对于课程的具体改进建议

  1. 建议明确课程评分标准。OO课的评分标准一直是一个非常困扰的问题,由于OO课本身内容就很多,包括课堂、作业、实验、研讨,其中作业中又有弱测、中测、强测、互测,各个测试中又有各种评分规则。助教和老师又从不透漏各个部分的具体占比、具体算法(或者给出一个公式但公式中不给出具体的数字比例),这让学生很迷惑。尽管学生上课的重点是学习而不在于成绩如何计算,但这是学生应该知晓的内容,课程组应该决定好具体数值并进行公布。有助教透露xx部分比xx部分占比更高,这种信息是学生应该有渠道知道的,而不是像秘密一样由学生猜测
  2. 建议优化互测体验。我认为,互测的目的应该是让同学们互相之间能够学习,而不是让同学们互相“作对”。现在的互测,我只感受到了同学之间的“心狠手辣”,没有感受到“互相帮助”。首先,我认为,可以用加分来激励大家阅读和测试他人的代码,却不应该用扣分来打击出现bug的同学。即使要进行扣分,也应该使得加分>扣分,使得互测整体是正和的,而不是零和的。其次,应该在互测内增加同学间的交流,即提供一个被hack的同学学习交流的机会,让他们能更好地优化自己的代码。例如hack的一方可以选择性地提示被hack的一方是哪个地方出现了错误等等。
  3. 建议增加实验的讲解。不得不说现在的实验确实能给到同学很大的帮助,但实验课下课后就完全关闭,这一点非常让人遗憾。如果在实验结束后,可以得到一份供参考的答案(或者一些提示),会给予同学更大的帮助。尤其是实验是填空型的题目时,同学们迫切地需要验证自己的思路和想法是否正确,这样才能更好地确认自己学习是否达到了效果。如果能在适当的时间(比如实验结束后的第二天、实验结束三天后等),公布实验的参考答案、参考代码、参考思路,那么实验课能发挥更大的作用。当然,如果实验课能有一定的讲解,那就更好了。
posted @ 2021-06-26 20:40  白丶枫  阅读(110)  评论(0)    收藏  举报