OO Unit4 & Final

OO Unit4 & Final

OO课程完结撒花

一、三次作业架构设计

1.层次化架构与数据存储

UML单元的三次作业,是完全的迭代开发过程。完成了对于UML类图,状态图与顺序图的解析,并且能够进行部分的规格检查。我采取了层次化存储处理的方式。在后两次作业中,我在MyUmlGeneralInteraction类中添加三个属性:MyUmlClassModelInteraction,MyUmlCollaborationInteraction,MyUmlStateChartInteraction分别管理UML类图,顺序图以及状态图。进而细分,针对UML类图,我们的查询主要是以类/接口为单位的,所以我建立了专门的管理类与接口的MyClass, MyInterface,管理相关属性方法,关联对端,继承与实现关系等。而在UML顺序图中,通过MyInteraction管理一个顺序图,通过MyLifeline管理一条生命线及其相关的交互。在UML状态图中,通过MyStateMachine管理一个状态机,通过MyState管理一个状态以及其转换。

而对于数据的存储,主要使用id为key, UmlElement为value对进行HashMap存储,同时使用name为key,id的容器为value,来方便根据名字的查询。

2.第三次作业的UML类图

OO Unit4 & Final_第1张图片

从架构的角度,本单元体现了OO的很多设计思想,包括UML图的各种抽象层次与动态维护,模块化设计。

3. bug分析

因为自己测试的不严密,导致第一次作业强测一个点出现超时的现象,后来发现对于接口继承的遍历仅仅采取树的遍历方法,导致菱形继承时重复访问部分节点,必然超时。

第三次作业强测出现了一个死循环,原因为对于类的循环继承判断,循环跳出条件有误,会使得从环外的元素遍历到环中时出现死循环,导致程序出现死循环。

综合分析本单元出现的两个bug,问题仍然出现在测试不够充分上。由于本单元数据的特殊性,之前使用的随机生成+对拍的自动测试方法已经无法适用。手动构造测试样例的结果就是很难做到覆盖所有可能输入,再加上自己对于可能出现的继承机制不全了解,导致测试只能做到对于一部分数据的覆盖,最终在某些细节上出现偏差。

这也进一步强调了充分测试对于程序开发质量的重要性。

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

第一单元

实现多项式求导。

第一单元可以看做从面向过程到面向对象的程序设计思想的过渡阶段,从第一次作业完全的面向过程到第三次作业被迫分类模块化层次化处理,仅仅用了三周的时间。此外,第一单元的训练重点还包括对于非法输入的判断,这是一个之前没有处理过的工作,却也是软件开发过程中保护软件正常运行的重要守门员。

纵观整个OO课程,第一单元的第三次作业仍然是自己做得最为困难的一次作业,分层求导的理念理解了两天,实现代码经过了两天,测试与优化经过了两天,最终权衡交上去了没有特别优化的版本。从这一次作业开始,我开始理解OO的思想与架构设计的重要性,体会到OO原则对于复杂工程化程序设计的独特好处,开始真正理解“分而治之”,“高内聚低耦合”的思想。

第一单元还是这四个单元以来唯一一个经历了多次架构重构,也在后面的单元中真正体会到,最初实现一个优秀的架构,会给迭代开发带来非常大的优势。

第二单元

实现多线程电梯的调度。

这一单元主要引入了多线程程序设计需求,调度算法的引入。线程的同步与互斥的主要需求是在保证线程安全的情况下,使得多个线程相互协作,并发执行,提高系统的执行效率。第一次接触多线程并发程序设计,使我把三次作业设计的目标都放在了减小线程间的耦合上,尽量使工作在线程内完成,这样的设计也与面向对象的思想相吻合。但是一些优化又需要在保证线程安全的情况下,增加线程间的通信,所以放弃了部分想到的优化。第三次作业使用的换乘与分配策略仍然是打表类型的静态策略,使得性能没有达到一个较高的水准。

三次作业都使用到了经典的消费者-生产者算法,消费者与生产者对于产品进行处理,对于托盘进行互斥访问。这样的模式最大程度的减少了互斥访问可能存在的问题。但是在理论课以及OS理论课中,还学到了相当多的其他实现线程互斥与并发的方法,以及java的各种锁机制,使得对于线程同步的理解进一步加深。

对于电梯调度算法的探究(FCFS, ALS, SSTF, SCAN, LOOK),也让我们提前预习了OS理论课的磁盘调度算法,再次体现了计算机科学领域知识的相通性。

由于多线程的设计模式需要模块化的处理,多线程电梯的设计一定是越OO越优秀的,这样的训练也让我们进一步熟悉模块化的设计,以及在线程与共享数据之间形成层次化的关系

第三单元

根据JML规格实现人际关系网络的构建与查询。

这一单元的训练目标为规格化设计,是一种契约式编程思想的体现。了解了JML规格的各种类型,方法规格的前置后置条件,不变量与约束等。整体来说这个单元的JML语言理解不算太难,更加难的是对于图的数据结构存储的选择以及图论算法的应用,来保证程序在规定时间内完成所有的工作。

自己在这一单元中并没有做过多的架构设计,数据结构的选择上多为散列(需要查找的容器),与数组(需要多次遍历的容器),算法选择上也相对比较朴素,导致强测出现部分超时的问题。这一单元的架构设计相对较弱,但是在理论课上老师推荐了一些层次化管理图结构的架构,体现了根据规格仍然可以设计出更加优秀的架构。

第四单元

实现UML图解析器

根据需要存储的UML类图的层次化关系建立对应的层次化关系进行处理,根据内部关系进行模块化设计,这既是UML类图面向对象设计的体现,也是解析时分层设计的体现。

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

在第一单元中,首先采用的是传统的手动构造边界数据的测试方法。之后受到研讨课大佬的启发,自己拼凑完成了生成+测试的简易评测机,使用批处理程序指令串联多个python以及java文件,并且在第三次作业的互测中测出了许多的bug。当时的对于测试的理解仍然停留在对于一定的stdin获得相应的stdout即可。

第二单元的多线程测试,仍然采用的是生成数据 + 运行 + 对于输出结果进行正确性分析(时间间隔是否合法,内部容量是否合法,每个请求是否完成),但是对于输入时间间隔的控制并不是特别好,采用的是输入新加线程并且sleep的方法,不过这样的方法已经足够检测出程序问题以及死锁。

第三单元使我对于测试有了更加深刻的了解,首先是通过规格配合JUNIT进行单元测试来测试方法的正确性,这样把测试从纯粹的黑箱细化了不少,通过写JUNIT测试也能够让我们更加深刻的理解规格的要求,起到了双向促进的作用。此外,大量随机生成黑箱对拍仍然在测试程序鲁棒性上得以适用。但是性能上的测试做的不够。

第四单元的测试有一点倒退三十年的感觉,由于本单元数据的关联性太强,自动生成黑箱数据已经不能使用。所以在本单元我再次回到了手动构造测试样例的阶段,并且尽可能的做到覆盖。但是强测数据显示,仍然有没覆盖到的测试用例,程序的鲁棒性不如之前几个单元。

四、课程收获

面向对象不只是一种程序设计方法,更是一种解决问题的思想。

面向对象的思想让我们能够更加高效与清晰的分析与理解生活中的问题,将其分而治之,模块化与层次化的解决问题,这是人生的哲学。

OO是一门很有成就感的课程。自己的成果与进步都是明显可见的。每次通过构思,写代码实现,测试再到提交,中测通过以及强测得分不错时都有不一样的成就感。

OO也是一门很肝的课程,周二布置作业到周四提交到周日互测再到周一出结果,宅家学习的一周又一周就这样充实又肝的过去了。

OO也是一门安排得十分有序的课程,作业的发布,梯度中测,互测阶段,bug修复,无论我们的软件质量如何,总会在这些测试与反馈中,真正的学到知识,获得成长。

研讨课,讨论区,微信群,私聊,OO带给我们的不止是自身的提升,还能感受到大家一起的进步。大家不同的思考与架构,分享自己实现使用的设计模式以及小trick,一起完成测试与对拍,帮助别人发现错误。在学习OO的路上,You are not alone.

五、一些小建议

  1. 希望第一单元的难度梯度能够更加缓和一些,建议加大前两次作业的难度,比如把嵌套组合与嵌套乘法组合分别分配给第二,三次作业。第二次作业和第三次作业的难度差距太大,使得完成第三次作业显得相当吃力。

  2. 建议可以调换一下二,三,四单元的顺序。四单元所强调的对于UML图的层次化抽象管理正好顺应了第一单元需要训练的抽象层次的目标,UML图特别适合初学者理解面向对象的思想,在多线程单元里面也需要顺序图进行分析。而将第二单元延后一个月左右可以与OS课的进程与线程同步的内容结合,从而让同学们更加深刻的理解程序并发的机制以及多线程安全的考虑。

  3. 第三单元的训练有一点脱离架构而侧重于算法了,在三单元的问题条件下,直接放在一个图里的朴素架构也不会出现太大的问题,反而在某些查询方法上,利用高级算法例如tarjan算法会得到更大的收益,这样对于规格理解的考察也不是重点了。此外,第三单元的实验也有一些脱离单元主题而另外拥有其他训练点。此外,放弃JML工具链吧

  4. 个人认为多线程部分三次作业的数量过少而规格部分三次作业的数量过多,可以在规格部分添加一些需要多线程解决的实际问题,使得同学们更加深刻理解java中保护线程安全的机制,而不要像我只会用synchronized。这样下来个人认为的学习顺序为:

    • 第一单元:面向对象的核心概念与入门:多项式求导系列作业
    • 第二单元:模型设计与层次化抽象管理:UML模型的入门介绍和解析
    • 第三单元:并发执行对象的状态与控制:电梯系列作业
    • 第四单元:规格化设计与多线程面向对象设计:某些新系列作业,综合线程控制和契约式规格处理
  5. 实验课的设置有一些不合理的地方。首先是开放学习的时间可以更长一点,比如提前两天左右发布,并且提前说明考察重点内容,而且重点内容最好为单元主题或者理论课主题,如果为改错类型希望能够给出具体错误数量以及可能错误的类型。本学期的大部分实验内容的设置还是比较合理的,比较突出的问题在于第三单元垃圾处理阶段的代码量太大,而且很多方法也没有JML语言进行约束,使得单元测试需要完全读懂代码,在规定时间内完成就显得很困难。

无论怎样,OO都是自己在大学生活中经历过的最有价值的一门课,虽然平时作业压力大,但是付出所获得的收获都是显而易见的。除了知识与作业考察内容本身,也没有像OS实验一样在开发环境,测试反馈上给我们带来多余的难度。所有的难与肝都让我们学有所得。

六、最后

线上学习对于OO课程的影响不算很大,所有作业,实验都按部就班的进行,录播的形式还可以多次播放。唯一的缺点可能就是课堂交流体验不佳。

最后感谢让这门课变得越来越好的老师和助教们,感谢一直分享学习经验,交流成长的同学们。

You've made us all strong.

你可能感兴趣的:(OO Unit4 & Final)