OO课程学期总结与第四单元作业

OO课程学期总结与第四单元作业

目录:

  一、第四单元作业分析

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

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

  四、总结课程收获

  五、改进建议

  六、线上学习OO课程的体会

一、第四单元作业分析

1.第一次作业

·类图

(1)指令分析

  在第一次作业中一共需要实现9个查询指令。在这9条指令中最复杂的指令应该是“类实现的全部接口”,这条指令需要一边沿着继承关系向上不断查询父类,并同时查找每一层父类实现的全部接口。由于作业中规定类只能单继承,所以所有的UmlClass可以组织成一个树林。但由于规则中允许接口出现多继承,所以所有的UmlInterface不能组成一个树林,只能组织成若干个有向图。

(2)程序架构分析

  第一次作业强测版本的类图如上图所示。在完成第一次作业时,自己偷了懒,并没有在输入全部数据后,对UmlClass和UmlInterface分别建立起图和树,而是采取直接莽的方法。每次查找类或接口的继承关系时,都去遍历UmlGeneralization去获得父子类或接口之间的继承关系。但是写完后发现,这种直接莽的做法不仅不会减少工作量,还会极大地增加代码量,使程序变的臃肿。

  其中GetOperationCount类仅仅是为了满足checkstyle的文件长度要求,而把GetOperationCount指令单独放在一个类里去完成。

  第一次作业仅仅是完成了最基本的指令功能,在程序架构上的层次设计还有很多地方值得完善。

(3)架构的重构

  在通过第一次作业的强测后,为了使程序具有更好的层次框架和更好的可扩展性,我对第一次作业中UmlClass和UmlInterface的数据结构进行了重构,将他们分别组织成树ClassTree和有向图InterfaceGraph的形式。

2.第二次作业

·类图

(1)指令分析

  在第二次作业中,新增了对顺序图和状态图进行解析的共6条指令。

  第二次作业新增的功能实现与第一次作业比较独立,可以就是相当于在类图的基础上,额外再构建出一个顺序图和状态图,然后根据指令执行相关的查询操作。

(2)程序架构分析

  程序的架构基本上沿用了第一次作业重构后的架构,主要还是针对UmlClass和UmlInterface进行建图,减少部分指令的计算工作量。

3.第三次作业

 (1)指令分析

  第三次作业相比于上一次是新增加了8条针对UML模型有效性的检查的指令,而图中的内容并没有增加,因此第三次作业的架构相比于第二次没有进行任何改变。

 (2)具体实现

  下面挑选两个较为复杂的有效性检查进行分析:

  针对R002规则:不能有循环继承(UML008)的检查,我采用的是检查一次所有UmlClass和UmlInterface的继承关系。在检查以某一Class或Interface的继承关系时,若该元素经过继承关系能够再次回到该元素本身,便说明出现了循环继承的现象,将且仅将检查的元素加入出现循环继承链的元素集合中,而对通路上的其他元素不予标记。这样做的优点是算法的正确性可以容易得到保证,就是对每个元素进行DFS搜索,看是否存在一条基本回路;缺点是算法的效率很低,因为在检查一个元素时,若经过该元素存在一个基本回路,回路上的起点便可直接加入集合中,不用再去单独重新就算一遍。考虑从此次作业元素个数仍然较少,我便选择了一次仅标记一个元素的算法。

  针对R003规则:任何一个类或接口不能重复继承另外一个接口(UML009)的检查,其和类图的查询指令“类实现的全部接口”的实现有相似之处。同样是沿着继承关系不断的访问父类,并且查找父类实现的全部接口。唯一不同的是增加了两个HashMap,分别用于统计经过的UmlClass和UmlInterface。每次访问一个新的类或接口时,总是现在HashMap中查找,若不在其中,则说明还未访问过,将其加入即可;若已在HashMap中存在,说明出现了循环继承的错误,再做出相关标记,把信息传递到最顶层的函数中去。R003的实现同样是一次只检查一个点,也存在着效率较低的问题。可考虑在递归查找中加入一些查询操作,比如继承自一个已知出现重复继承的类或对象,便不再需要继续向下查找了。

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

  在本学期总共四个单元的作业中,我认为第二单元多线程电梯与第三单元地铁系统最能够锻炼架构设计能力。

 1.第一单元

  第一单元的作业是围绕多项式求导这个主题展开的。

  在完成第一单元作业时,由于之前连最基础的Java语法都没有学习过,基本是一边查找学习Java的语法一边完成作业的。因此也就不太可能在架构层面花费足够的精力。在完成第一单元作业后,感觉尽管作业难度不小,但是并没有学到太多OO的内容,唯一比较有收获的就是学习了Java正则表达式的使用。

 2.第二单元  

  第二单元的作业是实现多线程电梯的调度,从第一次作业的单部傻瓜电梯,到第三次作业的多部智能电梯。

  第二单元的多线程电梯作业,让我真正感受到了OO编程的强大之处。在面对像第一单元那种偏静态的求导问题时,并不能体现出OO编程的强大之处。但是在面对需要多个对象互相合作,多线程并发的问题时,面向对象的编程思想就要显著优于面向过程的编程思想了。利用多线程的设计模式,并将各个类之间的协作关系理清楚,可以比较容易的写出多线程电梯的调度程序。比如如何将输入队列,调度器,电梯这三个对象独立起来,并使他们在多线程并发的条件下相互合、作完成任务。而且如果架构合理的话,在面对增量设计时也可以很好地满足新增需求。在第二单元的第三次作业中,引入了多部电梯,如果架构合理的话,只需要多“注册”两部电梯,程序的改动将非常小。

  而如果是传统的面向过程的编程思想则很难进行下去,不同状态之间的转移仅仅靠一个个独立的函数完全描述准确是困难的。并且在面对增量设计时,采用面向过程思想写出的程序的扩展性也不如OO思想写出来的程序好。

  在经过第二单元电梯作业的洗礼后,自己对Java的多线程编程以及OO编程思想的认识都有了进一步的提升。

 3.第三单元  

  第三单元的作业形式为阅读官方给出的JML规格,根据JML规格实现接口并补全代码、实现针对指令的交互功能。

  本单元的作业最终实现的是一个社交关系的查询系统。第三单元的作业看上去并不需要对架构进行过多的设计,因为所有实现的方法都已经明确给出了,但是合理的组织好程序的架构也是十分必要的,因为这对之后的性能优化有很大影响。个人感觉,第三单元的作业也是最接近实际开发的应用软件的,写作业的时候感觉也比较有意思。

 4.第四单元

  第四单元的作业是实现一个UML的解析器,需要能够支持对UML类图、UML顺序图和UML状态图的解析,并且要完成对八个有效性规则的检查。

  在完成这一单元的作业时,要实现的方法已经明确给出,但是如果想要完成好三次作业, 架构设计仍然是必不可少的。因为如果程序架构不合理,不能很好的构建出类之间的层次关系,将会导致程序的可扩展性很差,很可能就需要在完成新的作业之前,先对上一次作业进行大规模的重构。并且再加上一个类的文件最多不能超过500行,如果不能比较清晰地划分出程序的结构,500行是远远不够用的。

 

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

 1.第一单元

  第一单元的测试与找BUG基本上都是围绕"WRONG FORMAT"展开的,我自己就由于在正则表达式中使用了\s去匹配空白字符,导致在互测中被各种奇奇怪怪的空白字符砍了n多刀。这一单元的测试让我认识到了程序的鲁棒性想要做好不是件容易的事情,程序的鲁棒性也是考察程序质量的一个重要衡量指标。

 2.第二单元

  第二单元由于输入部分提供了官方的解析包,我们不再需要针对输入的格式进行处理,测试的重点也更多的转向了程序的逻辑正确性和多线程的安全性。在第二单元中由于多线程的存在,如果处理不好各线程之间的同步与互斥,是非常容易出现BUG的。而由于多线程BUG出现的不确定性,就算是做了大量的测试也不一定能够真正定位出BUG的所在地,最后只能通过一行一行地阅读代码去发现程序潜在地安全性。

  在构造测试样例时,我采取的策略是在一个小的楼层范围内、短时间投入大量的请求,以检查程序对电梯换向,承载人数限制等条件的实现正确性。

  这单元的作业也间接地让我认识到了在编程前做好设计工作的重要性。我记得老师在课上反复向我们强调过:测试只能在一定程度下改善程序的质量,但并不能从根本上提升程序的质量。一个程序的好坏,往往在其设计阶段就已经定型了。

 3.第三单元

  第三单元的作业是基于给出的规格实现出相应的类和方法。在完成这一单元的作业时,如果对规格阅读有纰漏,很可能导致自己的作业在强测时发生严重的翻车,而这正是我自己切身的体会。

  此外,第三单元的作业在正确实现功能的前提下,对程序的性能也有很高的要求,这意味着单纯的按照jml的语义去实现功能是不可取的,必须对程序的架构设计做出合理的安排。

 4.第四单元

   最后一个单元的作业取消了互测的环节,测试也主要是针对自己的程序展开的。第四单元在解析UML图时,由于对一些概念比较模糊,很容易出现理解不到位导致的实现错误。对于一些比较模糊的地方,主要采取阅读讨论区,针对讨论区中提出的一些坑点进行测试,以保证不会出现因理解错误导致的BUG。

四、总结课程收获

 1.面向对象的编程思维

  大二上学期学习的C语言课程主要练习的是面向过程的编程思维,我感到面向过程的思维方式在解决一些实际问题时会非常的复杂。在学习OO这门课程后,发现面向对象的思想更接近实际生活,在解决一些复杂问题时更加的方便。并且用面向对象思维写出来的程序也往往具有更好的可扩展性。

 2.编程能力的提升

  对于我这样一个大二上学期才开始接触C语言、数据结构的编程小白,每周一个大作业还是十分具有挑战性的,熬夜爆肝干OO的情况也是真实存在的。但是这一学期的作业走下来后,能够感受到自己的编程能力和debug能力得到了比较大的提升。

 3.jprofiler插件、StarUML工具等等

  这学期在完成课程学习和编程作业的同时,还学习到了许多实用的插件和工具。编程不仅仅是打开一个记事本简单地敲代码,如果能够将一些辅助性工具利用好的话,它们将对实现设计任务带来极大的便利。

 4.Java语言

  当然,这一学期一直都在用Java语言完成编程作业,也算是初步掌握了Java这一门编程语言吧。

 5.代码规范

  归功于checkstyle,我想如果让一个完全不懂程序的人去看我之前写的C代码和这学期的OO代码,它们也都会觉得这学期的OO代码更好看一些吧:)

五、改进建议

1.课上实验

  每次上机结束后,得不到任何有关实验的反馈结果。可能对于大佬来说,上机实验任务它们都可以轻松并且正确的完成,但是对于一些小菜菜,我们可能并不足以在限定的时间内完成上机任务,而课上实验结束后,就真的是彻底结束了,根本无法进一步查看和完善实验任务。

  因此,我建议课程组在每次试验后能够继续保持实验界面的开放性,并且提供出一些比较优秀的上机作业供大家学习。

2.作业难度

  在完成第三单元作业时,感觉对于性能的要求有些过于苛刻了,有点脱离面向对象的内容,像算法课靠近了。虽然有的实现可能复杂度比较高,但是正确性是保证了的,未来是否可以考虑在完成第三单元时依旧引入性能分。通过正确性的判定可以得到基础分,再根据CPU时间给性能分,这样感觉会比直接爆0让人心里好受点。。。

3.理论课内容

  UML单元中,感觉老师在课上对UML图中各种元素之间的关系讲的有一些少,所以在完成作业时会感到有很多把握不准的地方。希望老师在课程中能够再加入一些对UML图元素的讲解内容,以便同学们能够更好、更大胆地去完成作业。

六、线上学习oo课程的体会

  个人感觉线上学习OO课程还是比较容易适应的,因为无论是作业还是实验,通过线上的方式都是能够实现的,并没有受到多大影响。唯一有些遗憾的可能就是连给我们上了一学期课的老师都没能见到一面,哈哈。。。

posted @ 2020-06-19 16:07  嘟1嘟  阅读(133)  评论(0编辑  收藏  举报