面向对象学期总结&第四单元作业总结

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

目录:

  一、第四单元作业分析

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

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

  四、总结课程收获

  五、改进建议

一、第四单元作业分析

1.第一次作业

·类图

(1)指令分析

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

(2)程序架构分析

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

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

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

(3)架构的重构

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

2.第二次作业

·类图

(1)指令分析

  在第二次作业中,新增了对顺序图和状态图进行解析的共6条指令,以及对模型有效性检查的3条指令。在新增的指令中,我认为最复杂的不是对顺序图和状态图的解析,而是对模型有效性检查的后两条指令。

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

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

(2)程序架构分析

  程序的架构基本上沿用了第一次作业重构后的架构,主要还是针对UmlClass和UmlInterface进行建图,减少部分指令的计算工作量。但是由于自己比较作死,最后一次OO编程作业几乎是在作业提交截止前的十几个小时才开始写的,所以说时间过于紧张。再加上通宵写程序使人心力憔悴,实在是不想在程序架构的组织上再花费过多的精力,导致最后一次OO作业的架构组织不是很好 ,也算是一个小小的遗憾吧。

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

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

 1.第一单元

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

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

 2.第二单元  

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

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

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

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

 3.第三单元  

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

  本单元的作业比较有意思,从最开始一个简单的路径管理系统,到第二次作业扩充为无向图系统,以及最终第三次作业的简单电梯系统,每一次作业都是在前一次作业的基础上进行扩充,以满足更多的指令需求。这就要求对程序的架构有很好的把控,如果程序架构不合理,不能很好的构建出类之间的层次关系,导致程序的可扩展性很差,很可能就需要在完成新的作业之前,先对上一次作业进行大规模的重构。

  本单元的第二次作业相比于第一次作业只是新增了一个无向图的查询,如果想要偷懒,不顾及程序的架构设计,直接把所有指令的计算任务全都放在一个Graph类里实现还是有可能的。但是从第二次作业到第三次作业,继续这么做肯定是不可行的,因为这样做的话一个类的长度肯定是要超过500行了。本人在被这么坑了一次,在完成第三次作业之前就强行重构了一次代码,这个过程确实有一些痛苦,但也十分必要,加强了自己对程序架构设计重要性的认识。

 4.第四单元

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

  这里必须要承认一个错误,在完成第四单元的作业时并没有像完成第三单元作业时那样花功夫。最后一次作业甚至是在作业提交截至前的十几个小时前才开始阅读指导书,完成设计与编程的。最后算是熬了个通宵,卡着deadline把作业交上去的。

  嗯。。。。。。所以作业的架构设计要远远差于第三单元的作业,而且也没有时间对架构进行调整了,所以最后的代码风格分也是惨不忍睹,算是对自己态度不认真的一个处罚吧。

  希望等熬过了烤漆,自己可以去继续完善一下最后一次作业的设计架构。

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

 1.第一单元

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

 2.第二单元

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

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

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

 3.第三单元

  第三单元的第二次作业和第三次作业加入了许多最短路径以及最短路径的变体问题,在实现各最短问题的求解过程中,如果考虑的不全面,在算法的正确性上就无法得到保证的话,是非常容易出现致命BUG的。

  在后两次作业中,我都手工构造一些比较容易出现坑点的测试样例,用它们对自己程序的正确性进行检测。此外,在第三次作业中,还利用大佬写的评测机对自己程序的正确性进行了验证。

  在对别人的程序测试时,采用的是跑大量随机生成的样例的办法,但是最后的效果并不是很理想。

 4.第四单元

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

四、总结课程收获

 1.面向对象的编程思维

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

 2.编程能力的提升

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

 3.jprofiler插件、StarUML工具等等

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

 4.Java语言

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

 5.代码规范

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

五、改进建议

1.课上实验

  我认为课上实验有两点可以改进的地方:

  (1)每次实验课都是上午刚讲完课,下午就要上机考。这样做的本意是好的,希望同学们能够及时掌握课上所学的知识,更好地完成作业。但是对于一部分像我这样基础比较薄弱,反映比较慢的同学,仅仅通过上午的两节理论课是难以达到上机要求的。

   因此,我建议课程组在每次上机的几天前,都能给同学们提供一些具有针对性的预习材料,以便同学能够提前进行预习。

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

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

2.作业难度

  在完成第一单元作业时,有些同学可能是刚刚接触Java,很多Java的语法都没有掌握好,所以作业难度不易过高。在经历过一学期的所有作业后,我觉得第一单元的求导作业难度确实有一些大,尤其还是出现在课程初期,所以希望能够降低一下第一单元作业的难度。

3.理论课内容

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

  最后的最后,感谢老师们和助教们一学期辛苦的付出。这一学期走下来后,发现OO课程并没有之前传说的那么可怕,那么不好,整体的感觉还是非常不错的,能够感觉到自己的能力得到了一定程度的提升。希望OO这门课能够变得越来越好!!!

猜你喜欢

转载自www.cnblogs.com/syf17377376/p/11070089.html