OO第四单元博客作业
一、本单元架构设计
由于各次作业的迭代设计,以第三次作业最终版为例来解释架构。
-
MyClass
这个类中含有类图元素umlClass;这个类所包含的元素attributes、包含的操作operations、所实现的接口interfaces、与其相应的关联associations、与其关联的对端assocaitionEnds。这些属性都使用HashMap来保存,key采用每个UmlElement独有的String,保证不重复;value采用相应的元素。
这个类里还含有该类的直接父类parent,它所继承的所有类allParents(用HashSet保存)。同时,它所实现的接口也用ArrayList保存一次,以便后续操作遍历使用,允许重复出现。 -
MyInterface
这个类中含有类图元素umlInterfafce;接口所需实现的操作operations以及所需要的属性attributes、所含的父类接口parents(都用HashMap保存);为了满足后续函数需求,还用ArrayList保存了父类接口。 -
MyOperation
这个类中含有类图元素umlOperation;该操作所需要的参数parameters(用HashMap保存);该操作的返回类型以及参数类型。 -
MyInteraction
这个类含有时序图元素umlInteraction,同时用HashMap来储存时序图中的lifeline和endpoints以及attribute,使用HashSet来储存umlMessage。 -
MyLifeline
这个类中含有时序图元素umlLifeline以及umlEndpoint,在构造函数时,会根据传入元素来分别构造MyLifeline。同时,用两个HashMap来存该生命线接受以及传出的Message,HashMap的key就为UmlMessage,value就为MyLifeline -
MyStateMachine
这个类中含有状态图元素umlStateMachine。由于本单元一个machine之对应一个Region,所以还包含了一个元素region。 -
MyRegion
这个类中含有状态图元素umlRegion,相当于一个画布,存放状态图的各个状态以及关系。所以,里面用HashMap存放了所有的state,为了再分细一点,还保存了该画布中的pseudostate、finalState和普通的states。同时,还用HashMap保存了各个转移transitions。 -
MyState
这个类中含有状态图元素umlState、umlFinalState、umlPesudostate,这三者都在MyState中,在构造时根据不同的类型来分别构造。由于是采用不同构造方法,故还需一个String来保存id。为了理清转移关系,用了一个HashMap来保存它能转移到的状态,这个HashMap的key为MyTransition,value为MyState;用一个 HashSet来存能到达该状态的所有状态 -
MyTransition
这个类中含有状态图元素umlTransition,同时用一个HashMap来存所需的事件,key为UmlEvent,value为String,表示该Event的name。 -
MyResolve
这个类是一个解析器,主要是针对代码风格以及将解析UmlElement这个功能单独拿出来的一个类。根据输入的UmlElement,用HashMap来存储所有的umlClass、umlInterface、umlStateMachines、regions、transitions、interactions。并且根据输入的其他关系,来完善各个类中的属性,保存各个属性的联系。 -
MyUmlInteraction
这个类就是完成各个方法的类。通过解析器得到总体架构,然后对这个架构进行相应操作。

四个单元的架构设计以及OO方法理解的演进
-
第一单元
第一单元的任务是多项式求导。其实第一单元就是对Java这一语言的基本探索,同时一开始就要同学们体会架构的重要性。第一次作业,草草了事,急急忙忙弄清楚Java的语法、git的使用方法等等,用C语言的方式赶紧把题完成。于是第二次作业就惨遭重构,而且可惜的是重构以后时间不够,细节并没有想好,它成为了我唯一一次无效作业。重构的方式选择很重要,需要提前想好构造思路,并且有可能的话还要思考除此之外还能增加什么功能,使程序的可拓展性增强。重构的基础,就是要把所需的结构理解透彻。第二次作业时候,考虑过语法树和递归下降,可递归下降是对我来说非常陌生的概念,而语法树在数据结构中曾学习过,因此我选择了语法树。还有一点非常重要,如果选择了重构,就一定要尽早开始,重构过程中会遇到大大小小的实现问题,需要查阅大量资料和修复大量bug,是需要很多时间的。不过这一单元让我算是Java这门语言初步入门,初步了解了面向对象的思想,毕竟是面向对象与程序设计,架构上吃的亏也让我足以重视。同时,还了解了正则式表达、语法树、递归下降等方法。总体而言第一次作业还是比较难的,甚至是四次作业中最难的。
-
第二单元
第二单元就引入了Java中的王牌:多线程。电梯问题的解决无非就是要先理解锁的概念以及Java中对锁的操作,然后在用合理的架构来实现它。其实我认为这个单元理解才是重头戏,确定完架构之后,还是比较简单的(当然只是现在回头看起来简单)。
访问公共资源加锁,适当时候放锁唤醒,这是电梯线程并行的关键。如果设计不当,就会出现死锁的情况。当然,在了解的过程中,有许多设计模式,我采用的是典型的生产者消费者模式。这个单元还有性能分,因此架构和调度的选择还是尤为重要的。我尝试过换乘和其他调度策略,发现这些策略其实大部分情况下并没有按序分配和按需求分配来的好。如果想要继续优化,复杂度会大大提高。
-
第三单元
第三单元是对JML的理解。这个单元是最为简单的,只需要了解JML的语法并完成相应的架构即可。其实总体架构已经给出,关键就在于性能的把控。借这个机会,我又复习了一遍图的知识,并且还了解了新的算法,比如并查集。
-
第四单元
第四单元就是对UML的理解。这个单元其实对UML的理解还是比较容易的,但是具体落实到代码层面就比较痛苦了。在包里寻找对应的内容简直不要太痛苦,要理解和阅读的东西也非常多,不仅仅是UML层面上的,还有Java上之前没怎么用过的语法。这个单元的核心就是读懂UML图所包含的内容,弄清楚UmlElements之间的关系,然后选择出合适的架构把它们联系起来。但最开始的时候,真的是无从下手。
三、总结自己在四个单元中测试理解与实践的演进
这四个单元的测试,方法基本上都是一致的,都是手动构造样例来判断。先手动构造几个简单的样例来判断正确性,然后在进行几个复杂的数据点的测试。
第一单元的多项式表达,可以通过Python的包来获得正确答案,可惜的是我都去了解Java了,更没有时间来学习python,因此借助他人的评测机来跑了数据。
第二次作业是多线程电梯,本地测试的难度还是比较大的,本人就遇到过一次,在bug修复环节,什么都没修改重新提交就过了的情况。而且第二次作业的输出比较特殊,没有很好的办法解决,因此就着重检查电梯的开关的合理性以及临界条件的判断。
第三次作业的JML更多的是注重形式化验证,只要完美满足JML的条件,写出来的程序就不会有正确性错误。但是本单元喜提强测0分一次,原因就是没有多进行全面测试,算平均年龄的时候直接除以了0。还有为了防止超时,专门编写了一个反复调用图查询的样例。
第四次作业的UML的检查是利用官方包,构造几组样例来生成数据,与同学对拍来debug的。在StartUML中手动构造模型,特别是最后一次作业,对每个异常进行数据构造,进而来排查bug。
四、总结自己的课程收获
一路走来,感慨万千。
这门课是以匆忙揭幕的。寒假的时候没有做pre,一开学就开始了第一单元的任务。还记得当时手足无措,面对第一单元的作业,不知道Java语法,甚至连怎么提交都不会。第一次作业摸爬滚打,勉强提交。迭代设计的要求直接让我在第二次作业上重构。时间太紧了,它成为了我的无效作业。当时一度认为自己真要挂科了。还好有同学的帮助解答,和讨论区里同学的帮助,才让我度过难关。
这学期的每一周都是这样,周三开始,由于其他事务的影响,常常是周四或周五才开始看OO,然后自己去查找相关资料,又怕写出来架构出错进行重构,总得思考很久很久才能开始。不得不说,这真的是一门很折磨的课,为它通过宵,赶过ddl,踩线提交没过等等。现在回过头来,也发现自己的收获是巨大的。首先掌握了Java这一语言的基本语法,同时了解了面向对象与程序设计的核心思想与架构的取舍选择,过程中还了解了许多算法理论,也知晓了JML和UML这些曾经有所耳闻的知识,还有对Java设计模式的了解、多线程编程的了解、代码语言风格的注意等等,其实它就是在大一下数据结构这一课程的基础上,对我代码能力的进一步提高和拓展。
有了这门课的基础,我相信以后在其他语言或者其他程序的设计中,我能发挥在这门课上学到的严谨逻辑与优良习惯。它为我在今后的学习中打下了牢固基础。所以,尽管过程苦涩,我内心还是对这门课充满感激的,它理应是六系的王牌专业课。
五、改进建议
-
OO第一次作业难度太大,一是刚入门语法,二是本身程序的设计也较为复杂,可以稍微降低一点难度。第四单元难度也大,而且还进入了考期。难度梯度设置有点费解,可以适当调整,或许可以与JML换个位置。
-
前几次博客就在提倡画出类图和协作图之类的,本来任务就繁重,又把第四单元的内容混到前面来提前学习,没有必要。老实说,我写博客的时候对类图和协作图一头雾水,它的内容繁多,写出来又是摸索着写的,到第四单元的时候,又搞忘完了,还得重新学习。
-
建议课程组丰富课程其他方面的内容。比如给出一些更多参考的阅读资料来帮助学生架构选择和理解内容,而不是自己学习时大海捞针,效率很低。再比如对于测评机的编写,也可以提供一些思路,帮助同学们更加提高。
浙公网安备 33010602011771号