面向对象Unit 4——UML & 学期总结
面向对象Unit 4 - UML & 学期总结
19373345 刘兆薰
1、总结本单元作业的架构设计本单元考察的是对于UML类图,时序图和状态图模型的构建以及执行相关的查询操作
本学期OO的最后一个单元要求写一个UML图的解析器,将比较复杂的UML图解析成若干个UmlElement(由官方包实现),我们只要对解析好的元素进行组织和编辑即可。
本单元作业难度相对适中,没有第一第二单元那么变态也没有第三单元那么轻松。在本次作业中,官方包对输入进行了初步的处理后,我们只需要判断各个element的type进行分别处理即可,在构建时特别注意的是输入顺序,会出现类似先有类中属性再有类这种情形,所以为了避免错误我是先对输入进行分类,将不同种类元素放入各个list中再按照合理顺序挨个遍历list去进行图的构建,对于特定元素查询,例如class,我是新建了一个MyClass类进行数据管理,而在UmlInteraction中是用的key为id,value为MyClass的Hashmap进行查询,由于后续会有重名的判断,所以对于不同element我还有一个key为name,value为id的Hashmap用于查询对应name是否重名,未重名则可得到对应id。
本单元的难度主要来自于类的继承,尤其是接口,可以多继承,我自己的处理策略是类似并查集的实现,从某一个类(接口)开始,往父节点找,直到找到头或者找到已更新相关数据的节点,返回时路径压缩将经过的节点相关数据都进行更新并把更新标记设置为true,此后再访问到这个节点就可以直接获取数据而不再往它的父节点搜索。格式检查时的难点在于对于循环继承的判断,我的做法是深搜,从一个未遍历过或者未加入答案Hashset中的类开始搜索,搜索时更新经过路径,如果出现重复则说明有循环继承。另一个难点是对于接口重复继承和类重复实现接口的检查,接口重复继承检查的实现类似是上文所说的递归,在判断时如果父亲接口已经重复继承了那么子接口也重复继承,没有则去挨个进行元素判断,而类重复实现接口的检查需要考虑父类和子类实现接口的关系,父类若重复实现则子类也重复实现,若父类没有重复实现,则把父类实现的接口和子类实现的接口进行合并看是否存在重复,对于类实现的接口还需要考虑到接口的多继承。
2、总结自己在四个单元中架构设计及OO方法理解的演进
第一单元
现在反观自己第一单元的多项式求导代码真是不忍直视。由于第一次接触面向对象的思想,我在第一次作业几乎还是被禁锢在面向过程的圈套中。第一单元表达式主要是为了提升我们架构设计的能力,将一个复杂的问题进行细分,再处理,难的地方是如何做到良好的可拓展性,另一个是分而治之以后如何合并答案以及进行优化。
我在第一单元第一次作业就几乎没有考虑到可拓展性的问题,于是第二次作业就完全重构了,也得益于第二次的重构,第三次作业写的就很轻松,感觉第一单元对我影响最大的就是写代码时不能只考虑眼前的苟且,还有迭代,以及将某些有共性的元素划分为一个类,在通过继承的方式实现多态。
在第一次作业中,最大的收获是对递归的使用可以更加得心应手。
第二单元
第二单元多线程电梯,刚开始第二单元时理解多线程的原理花费了很多时间,因为对于那时的我来说,多线程运行是一个全新的东西,以前写面向过程(C语言)时从未接触过。理解以后就到了麻烦的同步互斥问题了,最令人头疼的是bug的不可复现性,发现死锁了,准备找bug,第二次运行可能就能正常运行了,也就是n次正常不代表没问题,一次死锁那就一定有问题,当时出现死锁也就能从代码本身逻辑上去分析,然后构建可能死锁的访问序列去判断。当不会有死锁发生时就要考虑如何调度能够使得效率增加,虽然考虑了很多理论上优化的操作,但实际测试确都是负优化,所以代码运行不能脱离实际。
在第二次作业中,最大的收获是对多线程的理解可以以很好的姿势入门。
第三单元
第三单元JML主要是考查的对于JML规格的理解与实现,当然这种实现不能生硬翻译JML语言,否则性能可能会很差,所以要结合图论中的算法对于具体实现进行各种优化。JML的学习让我对于规范化代码有了更深层次的理解,自然语言的描述难免会出现二义性,JML则可以很好的避免这一点。这一单元总体结构由官方代码给出了,所以我们只需要选择不同的容器进行数据的存储以及构建不同信息的图模型进行查询与计算。
在第三次作业中,最大的收获是了解并熟悉了JML的读法,为之后工业界代码编写打下基础。
第四单元
第四单元则是UML图模型的构建,由于UML图的层次结构十分清晰,自顶而下依次用合适的容器对元素进行存储,再在具体类中构建上下级关系,最后根据需求进行数据分析处理即可完成,这一单元主要花费时间的原因还是对于UML的不熟悉,对于好多地方不确定是否有这种关系以及可能需要反复复习元素与元素之间不同关联的含义,而涉及到图论的算法难度并不算大。
在第四次作业中,最大的收获是对UML图的分析达到了更高的高度,并且掌握了图论的一部分算法。
3、总结自己在四个单元中测试理解与实践的演进
第一单元
由于力不从心,没有写自己的评测机,导致第二第三次作业出现很多bug。主要的debug手段是自己手动构造自认为比较容易出错的数据,然后和同学对拍。
第二单元
我用python构造了一个评测机去完成正确性检验,但是除了正确性,运行时间也是非常关键的一个环节,我只能通过估计的方法来判断自己代码的时间是否超标。
第三单元
第三单元的测试依旧是依靠python生成随机数据集并与同学对拍进行正确性检验,再输出时加上运行时间用以判断代码的性能好坏。
第四单元
第四单元的测试由于测试数据实在是太阴间太难造了并且没有互测环节,遂作罢。
总之,从来没有写过评测机的我体会到了评测机的必要性,可以在最终测试前找出很多或严重或轻微的问题。并且评测机的出现可以大大降低debug的时间成本和精力成本,在之后的学习工作中肯定会大大用到评测机,故自建评测机的能力还是很重要的。
4、总结自己的课程收获
学习了面向对象课程之后,肯定首先收获的是相关的专业知识,比如面向对象编程、多线程、JML、UML等;也收获了许多“软能力”的提升,比如在一个学期的学习之后我发现自己更适合面向对象的思想而非面向过程的思想,也让我意识到无论是在学习中还是之后的工作中,在动手敲代码之前,花足够的时间精力设计架构也许比写代码本身还重要,因为一个好的架构绝对可以避免很多编写代码时不必要的麻烦。
本学期的面向对象课程也让我真正意识到人的潜能是可以被激发的。许多次,尤其是前两次作业,我看到作业要求的第一眼都感觉无从下手,或是写到中途发现举步维艰,又或是后知后觉发现不得不重构时的崩溃,但最终还是都成功做完了每一次作业,并且成绩都还不错,这是我绝对不会后悔的一点。另外,我也明显可以感觉到自己的代码能力较大一大大提升,这是非常值得欣喜的。大一顶多可以写到四百行,但是这学期从第一次作业开始,代码量就大大增加至千量级,让我走出了自己的舒适区,不断发掘自己的能力。
OO绝对不轻松,但是能力提升就是如此,在成就感和挫败感之间不断来回,并最终回到成就感。
5、立足于自己的体会给课程提三个具体改进建议
- 强烈建议实验课结束后公布参考答案;
- 在一个新单元开始时可以对之后的作业方向(内容)进行一定程度的提示,以方便初始架构的选择以及后续增量开发;
- 第一单元的难度太大了,
可能确实菜是原罪,可以在之后的作业中适当地降低第一次作业的难度,然后在中期再来增大难度。临近期末的作业难度也可以小一点,可以考虑调换UML和JML的顺序。

浙公网安备 33010602011771号