BUAA OO Unit4 & Final Summary
一. 第四单元架构设计
总的来说,这次作业的架构设计比较清晰。我在第一次作业中按照类的层次对类图元素进行了解析,实现了MyClass类来复现UML类图中的Class。后两次的作业基本上是在第一次作业架构的基础之上进行扩展,所以完成得比较轻松。因为根据自上而下的层次进行了拆分,类的长度和复杂度控制得比较好,有效地避免了类长度超出CheckStyle限制的情况。
第一次作业
这一次作业中,我对UML类图元素做了本地的解析,实现了MyOperation
,MyOperation
,MyClass
等类,复现了原本UML类图中的层次。
其中MyClass是其中最为关键的类,对内,它存储了一个Class中的所有信息,包括所有属性,所有操作方法,父类,所有实现的接口和关联的类等;对外,向上层了查询类中信息的方法,比如属性数量,顶层父类,全部实现接口等。这样,上层结构想要查询类的信息时,仅需要调用MyClass中提供的查询方法即可。
对于类图元素的存储,采用HashMap建立了从名字到Id,从id到元素的映射,可以快速地利用名字查找元素,并且考虑了重名的可能性:
- HashMap<String, ArrayList
> className2Id - HashMap<String, MyClass> id2Class
对于MyClass中的查询顶级父类,全部实现结构等方法采用了递归的方式进行实现。同时,未来提高效率,增加了冗余存储,实现了缓存机制。
在解析元素时,实现了专门的主解析器来对元素进行按层次解析:先遍历一遍将所有元素进行分类,然后按照Parameter->Attribute, Opetion->Interface, Class->Generalization, Association的层次关系构建起类图。
对于顶层类MyUmlInteraction
来说,仅需要将所有元素交给主解析器解析,然后根据指令调用MyClass中相应的查询方法即可。
第二次作业
第二次作业增加了时序图和状态图,整体的架构设计依旧沿用第一次的分层次的设计。因为涉及到三种UML图,所以对于不同的图,新增了一个交互类的层次,每种图的交互类再与总交互类进行交互。
第三次作业
第三次作业是有效性检查,架构设计与第二次作业相同,增加了一些有效性检查的方法。
对于一些有效性检查,如R003和R004,可以和类图查询中查询类实现的全部结构这个操作联系起来,在进行检查的同时就将找到的全部接口缓存起来,这样在查询的时候可以进一步提高效率。
二. 四个单元的架构设计及OO方法理解的演进
第一单元
第一单元对于我来说是一个极大的转折点,从完全的面向过程设计,到开始理解什么是面向对象的设计。第一次作业到第二次作业期间,我经历了一次非常彻底也非常痛苦的重构,深刻地记得周三那天我心态崩溃了一整天,直到周四凌晨一点到时候,才感觉慢慢摸出了一点门道。
第一次作业的时候,我虽然抽象出了poly类,但是poly类中的求导操作依旧非常面向对象,并且解析表达式全部都放在了MainClass类,等于用两个类分别面向过程来处理面向对象设计。这样的做法使我后来的迭代开发遇到了非常大的困难,于是从第二次作业开始,我学着抽象出了表达式类,项类,各种因子类,采用了接口和归一化的设计方式,并且将解析表达式这个操作从MainClass中剥离出来,每一个类只负责自己的工作。这样设计的好处给我第三次的代码迭代带来的极大的好处,我能够快速地完成第三次作业,并且还有时间做了一些优化。
第一次作业是我第一次接触到了面向对象设计的方法,每一个对象只管理自己的数据,只负责自己的工作,学会将每一个类权责划分明晰,减少类与类的耦合度。
第二单元
第二单元进入到了多线程部分。其实第二单元里,我更多去关注了线程间交互和线程安全等问题,对于架构设计有些懈怠,这也导致我第二单元的整体架构并不是很好,三次作业都存在这一定程度的重构。
第二单元给我最大的收获应该是java设计模式,学习并且实战了单例模式、工厂模式、生产者消费者模式和Worker-Thread模式,并把这些模式运用在了作业之中,规范了代码的架构,也确保了代码的可靠性。
第三单元
第三单元是JML规格的学习与使用。其实第三单元作业的难度并不是很大,难点反而是放在了算法实现上。而对于面向对象的理解方面,如果说这个单元给了我什么收获的话,应该是课程组通过JML规格,向我们展现了如何正确地实现代码的逐层迭代开发。同时,理解JML规格并代码实现,其实并不是简单的看JML写代码,而是需要我理解JML规格之下真正的需求,并根据所理解的需求,采取最高效的代码实现。
另外这一单元我学会了Tarjan算法,虽然没什么卵用,虽然暴力DFS也不会爆TLE,但是让我看了整整一天才看懂的算法我必须提一下(要不然过两天就忘光了)。
第四单元
第四单元是UML图解析,也是我觉得最有OO内味儿的一单元,因为UML模型层次的设计本身就是面向对象设计的一个很好的例子。这一个单元的架构设计应该是最令我满意的一次,测试的结果也不错,也算是给OO课程画下一个完整的句号了吧。
随着四个单元的层层递进,我的代码架构也从开始的一团浆糊到层次逐渐清晰。也理解到了一点面向对象设计思想的皮毛,在解决问题的时候,不再着眼于将问题的解决拆分成一个个步骤,而是抽象化建立模型,每一对象都描述了自己在解决问题过程中扮演的角色,各司其职。
三. 四个单元中测试理解与实践的演进
我在四个单元中使用的测试手段基本都一致,采用了手动构造边界数据集和评测机覆盖性测试相结合的方式。
- 手动构造边界数据集:在通过中测之前我主要是通过手动构造一些边界数据集的方式在测试代码,这种测试方式是最有效的,而且对于保证代码可靠性也是最必要的,但是问题在于单纯通过手动构造样例,很难做到全覆盖的测试。
- 评测机对拍:通过评测机进行黑盒测试是我四个单元最主要的测试方式,甚至到中后期基本完全依赖于这种测试方式。这种测试方式覆盖性极强,而且随机数据的方式有时甚至 能照顾到一些我们没有考虑过的情况。并且靠自动化解放双手,省时且省力。但是黑盒测试的方式也有其劣势,一方面,写一个评测机的难度和代码量不亚于写一个单元作业,尤其第二单元电梯运行结果的检查部分,和第四单元UML图测试数据的生成;另一方面,这种测试的正确性在很大程度上依赖于评测机本身的正确性和所生成的数据是否真的足够随机,稍有不慎就会出现用bug测试bug的尴尬局面。
还好大体上我没太翻过车,lucky。
另外非常值得一体的就是junit单元测试,我是在第三单元接触到的junit单元测试,虽然之前又看乔佬公众号写过,但是自己并没有实践。在第三单元的时候,开始尝试使用junit进行一些单元测试。我认为junit单元测试最大的意义,一个是能够用测试来驱动代码开发,另一个是能够方便地进行回归测试。
四. 课程收获
有句讲句,OO这门课给我的体验还是很好的,收获很大,不过彩虹屁留着感言再吹,这里说说我的收获:
-
学会了一门新语言:java
-
学会了又一门新语言:python
-
逐步构建起了面向对象设计的思维模式
-
学会了多种java的设计模式:单例模式,工厂模式、消费者生产者模式......
-
学会了代码的迭代开发:重构一时爽,一直重构一直爽
-
测试能力得到了极大的提升:从程设DS时期的面向测评机编程,到自己测试自己代码
-
一颗勇敢的心:一周一次作业有时候压力是真的大,总之抗压能力是显著提升了
-
学会了交流合作:人生第一个测评机就是在小伙伴们的合作中诞生的
五. 三个具体改进建议
- 实验课前期的几个有关设计模式的实验体验感挺好,但是后期一些实验的目的有点意味不明。尤其多线程实验中售票窗口实验,需要sleep一定时间才能得到正确结果,而且感觉和Worker-Thread模式(没记错的话是这次实验?)关联不是很大。另外垃圾回收那次实验的初衷确实很好,但是我个人认为,阅读一份代码量不小的工程,并且利用junit测试寻找出所有bug确实不是俩小时能干完的事。
- 寒假预习部分和第一单元作业的跨度其实有点大,寒假预习部分能够帮助我们快速熟悉java语言,但是我依旧没能很好地对面向对象有一个初步的概念。于是很多同学在第一单元一、二次作业中依旧采用非常面向过程的方式完成作业,然后导致第三次作业难度指数飙升。所以,或许可以在寒假预习中提供一些面向对象相关方面的过渡和引导?
- 另外关于实验课没有反馈结果这一方面,也就是实验课过后不提供题目及答案。既然前几届一直都是这样的形式,课程组必然有相关方面的考虑。不过我还是没太想通其中的缘由,我认为课后提供题目和答案能更好地帮助我们知道我们的错误并且进行学习改正,所以想问一下原因。
六. 线上学习oo课程的体会
其实我感觉OO课是被迫线上授课的课程中,受影响最小的一门课了,尤其对比隔壁OO课来说。首先,OO课程的考核方式重点在于每周的单元测试,而这一方面基本不受影响。而对于实验课来说,在家进行实验和在学校机房进行实验差别也不太大。
或许从另一个角度来说,线上授课也带给OO课程了一些好处。比如网络匿名心理,其实能够提升同学们参与讨论的积极性,同学与老师之间思维的碰撞在很大程度上能够帮助同学更好地理解课程内容。另外,课程录播的形式,虽然让同学和老师无法面对面交流,但是也使得同学能够在自己不能理解的地方多次反复观看,在上完课之后如果还有不清楚的地方,还可以回头看视频。
如果说线上授课有哪里不好,那就是企业界人士分享的交流研讨课内容没了。(怨念)
七. 最后一点小感想
其实我早在大一就对OO课的“威名”略有耳闻。最早,我是从认识的六系学姐口中得知的OO这门课的,当时我看着学姐一边写博客,一边对我吐槽OO课程。我对学姐那句“有对拍机的大佬能把你所有的bug全部拍出来”印象特别深,这也是促使我从第一单元就开始尝试写对拍机的一个重要的原因。我对OO课程的另一部分印象,来自大一学业导师荣文戈老师的疯狂“劝退”。也就是那时听闻了“一个非常优秀的学姐,写OO作业写到凌晨一点,打电话给家人哭了一场之后抹抹眼泪继续写”的故事,给我留下不小的阴影(笑)。
但是在我亲身体验完OO课程之后,有一说一,体验感是不错的。一周一个作业的压力确实挺大,但是其实作业的难度设置基本上是很合理的。三次作业迭代的方式也很好,能促使同学们尽量去思考一个好的代码架构。从四个单元不同的偏向,也能看出课程组蕴含在其中的对面向对象的理解与思考。虽然课程依旧存在一些小问题(部分实验课、频繁改动的指导书和官方包),但总体来说,OO课程的完整度和成熟度已经非常高了。
当然我也看到了往届助教学长对OO课程的吐槽,不得不说改革前OO课的制度确实一言难尽。所以真的很感谢为OO课程改革和设计投入心血的老师和助教们了,希望OO课能够越办越好!