北航2020年OO第四单元总结
题外话
在前三个单元的博客总结中,我们需要给出自己架构的 UML 图。然而我当时对 UML 并没有什么深入的理解,只是通过 IDEA 来生成,并根据表层的信息粗浅地分析代码的优劣。可就在最后一次研讨课上,我被老师提问关于前三个单元使用 UML 的相关问题,羞于理解不到位,我一时语塞,只能搪塞过去。可是经过这一单元三次作业的磨炼,我可以自信地说,UML 常见的各种图、元素、关系我基本上都比较熟悉啦!
咳咳,下面进入正题。
1. 架构设计
1.1 第一次作业
第一次作业的主要任务是实现一个简单的 UML 类图分析器,主要还是带领我们初步认识 UML 的基本要素。可俗话说得好,万事开头难。在阅读第一次作业指导书的时候,我基本上是处于懵X的状态,对 UML 的大体结构几乎一无所知,对那些复杂查询的实现也是一脸茫然。后来在反反复复看了几遍录播视频之后,并且在这篇博客的帮助下,逐渐理清了一些元素的内容和它们的关系。
具体说来,我针对需要重点操作的三种元素分别建立了MyClass
、MyInterface
和MyOperation
三个类,并增添所需的属性和方法,最终由MyUmlInteraction
统一协调调用,实现要求的方法。在这个大的交互类中,我又根据 id、name 等特性用不同的容器灵活存储元素,使完成功能更加方便。在实现难度和代码复杂度的权衡下,我先递归预处理得到每个接口的所有父接口,而对类的父类每次调用方法时才获得。因为我粗略估计接口的多继承特性会使非缓存做法复杂度极高,而类的单继承特性以及数据规模的限制并不会带来大的时间开销。事实证明,强测中菱形继承的数据点卡了一些人,而我的做法存活了下来。
1.2 第二次作业
有了第一次的铺垫,后面的学习曲线就相对平滑。第二次作业我们学习了状态图和顺序图的相关知识,虽然新增的元素不少,但是要实现的功能比较友善。和第一次作业的思路类似,添了两个类MySM
(SM 指 StateMachine) 和MyInteraction
,强测无事发生。
1.3 第三次作业
第三次作业需要我们捕捉 UML 中的异常,工作量有了不小的提升。看着险些超出规定行数的MyUmlInteraction
,我陷入沉思:这分明就是三种完全不同的图,为何要混在一起交给一个类集中处理呢?说干就干,我对代码进行了一次小小的重构,对每一种图分别构造ClassMan
(Man 指 Manager)、StateMan
和SeqMan
三种专职处理类,将MyUmlInteraction
中的各种任务下派到这三个类中处理,让整体结构更清晰,更具层次化。有点小意外的是,强测超时一个点,是因为异常处理的算法选择不当导致处理接口的多继承超时。第一次作业能想到这一次就忽视了,咋回事?最后一次作业不能飘啊!
2. 四个单元架构设计及对 OO 的理解
每个单元的架构设计在相应的博客中均有所总结,不做赘述,这里我想从宏观的层面上谈谈。
整体来看,OO 课程就是围绕面向对象这一中心思想,从四个各有侧重的角度分别阐述,让我们在脑海中构建完整的 OO 体系。
第一单元初识 OO,我们需要掌握基础概念,完成层次化结构设计。这一单元算是让我完成从面向过程到面向对象过渡的第一步也是最关键的一步。第一次作业纯面向过程写的痛快,却让我永远忘不了日后重构时的痛苦。后两次作业次次重构,为的就是代码能更加面向对象一些,从而提高可扩展性和可阅读性。在一次次的思维阵痛中,我逐渐加深了对面向对象内涵的领悟,在对工厂模式的学习中体会到多态的威力,初步完成了向面向对象设计、层次化设计的蜕变。
第二单元考察对象的运行时行为状态与并发控制,注重线程安全设计。整体上来说,这一单元可以算得上是整个课程的难度巅峰了。它的难度不仅体现在需要深刻把握电梯和人的请求这两种对象的种种行为,更要从更高的维度协调各个对象之间的交互,稍有不慎就会陷入死锁等线程安全的泥淖。这一单元中,我真切体会到可扩展性的优势,在第一次作业的时候就把架构完成好:电梯线程和调度器对象各司其职,并且囿于本人实力,我在正确性和简洁性的 trade-off 中做了稳妥的打算,也就是着眼于每一次线程交互,用常规的方法、容器换来对运行状态的洞悉。架构设计虽稍显臃肿,但在这样一种框架下,我对于每个对象的行为均了然心中,可以从多线程的角度更深入地审视面向对象的精髓。
第三单元需要理解规格的概念,完成规格化设计。由于教学团队已经为我们勾勒出大体框架,这一单元的重点就是理解 JML 的语法,并用代码语言准确无误地表达出来。然而许多一心盯着分数,只管正确完成作业的同学却忽略了一件事:这一单元实现的是一个迭代开发的小型人际关系网络,既和我们的日常生活走的很近,也是面向对象思想最典型、最直观生动的代码体现,这可是再好不过的学习资料啊!恰巧当时作业量不算太重,我就在闲暇之余过了一遍教学团队的代码,梳理了一下 Person、Group、NetWork 的实现方式和交互关系,官方的打样让我受益匪浅。
最后一单元从更宏观的层面抽象出系统行为,完成模型管理与模型化设计。在这一单元的代码编写过程中,我对 OO 的理解更进一步。比如,第一次作业针对每个元素的方法各个击破,第三次作业针对又图的差异将任务分散到各个层次的对象中,整体的架构可以称得上是层次分明,类各尽其能。
3. 关于测试
说到测试,那可就是我的软肋了。相较而言,第一单元的评测逻辑较为简单,但我还是费了九牛二虎之力才写出来一个评测机,却因过于简陋仅仅测出部分 bug,对某种特定条件下的 bug 却无能为力;第二单元写代码占据了大量时间和精力,再无法写出像样的评测机。而且我的相对低级的设计反而不容易产生 bug,借了一位同学的评测机草草地测了一下,然而还是有一个边界条件产生的 bug 被忽视;第三单元使用 JUnit 对一些简单的方法进行了测试,可是懊恼于这种方法的繁杂,我并未做到全方位覆盖,导致第一次大翻车;第四单元由于数据的特殊性,手动画图,针对各个需求捏数据,却在精心设计的大数据面前败下阵来,直接 TLE。回顾这一路的测试历程,个人感觉理解逐渐加深:从最开始的用少的可怜的 Python 知识写出几乎没啥用的评测机,到后来学会借助工具,学会预测 bug 来源从而针对性构造数据。但整体来说,和那些玩转评测机的大佬还是相距甚远,Python 知识欠缺让我举步维艰,特殊数据、边界范围数据时常无法考虑周全,需要我好好反思。这也许说明了我与测试工程师一类的职业注定无缘了呢,哈哈
4. 课程收获
首先,由于 OO 课是以 Java 语言作为承载,我在代码书写中通过各种渠道也算是熟悉了 Java 基础语法,初步掌握了这门常年霸占编程语言排行榜首位的语言,为今后的职业发展打下了坚实的基础;
其次,其他一些周边知识的学习也是收获满满:git、markdown、正则表达式、多种多样的设计模式…… 物超所值;
另外,抛开语言本身,这门课给我带来了编程能力的无形提升。这一学期既有数量也有质量的代码训练,让我灵活运用代码语言解决实际问题的能力增长,尤其是后两个单元,加强了对数据结构和算法的考察,初步锻炼了我作为计算机专业学生的基本功;
最后,也是这门课的核心,它带给了我面向对象的新思想。我们知道,在如今的软件开发相关职业中,面向对象是一个不可或缺的理念,它是大型程序设计优良性能的保障。我们首先在编写代码的实践中完成对 OO 从感性认识到理性认识的过渡,再在实践中完成对 OO 认识的真理性的检验和发展,不好意思,最近马原学的有点多。在认识和实践的交互中完成思维的飞跃。比如我现在如果要完成某一项代码任务,就会摒弃面向过程的旧思维,而是不自觉地从面向对象的角度思考,将问题引入规范化,模块化、层次化、简洁化的方向,这将是非科班出生的同学永远都无法比拟的优势。
5. 一些小建议
经过这几年的改革,OO 课从知乎上大家吐槽的对象逐渐变成了交口称赞的优质专业课。不论是教学内容、作业要求还是评测方式,都有了很大的改善(我对以前的课程认识仅来源知乎所见,如有不当请指正),我自己的个人体验也是非常好。本着希望 OO 课越办越好的愿景,我仅从个人感受斗胆提几点建议:
- 实验课的组织形式还可以更完善一些,比如可以在课程开始前列出实验提纲,提供更多元的学习资料,试验后提供启发式答案等等;
- 这么多次研讨课上下来发现,有些同学可能仅仅是垂涎于分数,分享的内容要么只是搜索引擎结果的糅合,要么脱离作业,不知所云。建议适当把控研讨课分享门槛,既能让乐于分享出真材实料的干货的大佬获得应有的分数,也能让像我这样的菜鸡在聆听之后真正有所收获;
- 像下图这样的情况确实让人看着别扭,(明明只得了 5 分,却是绿色底加上一个对号)建议可以将评测界面做得更完善些,针对不同的分数可以有不同的显示。
6. 线上学习体会
线上学习,有利有弊,但绝非长久之计。就个人体验来看,好处是可以自主决定学习之间,且可以反复观看某一部分内容直到完全理解为止;坏处就是学生对着冷冰冰的电脑屏幕听课,一来缺少和老师面对面的交流,缺少实时的反馈,二来因为老师也可能是对着冷冰冰的电脑屏幕讲课,双方的积极性都无法调动,学习效果反而可能会大打折扣。但是得益于网上平台的完善,线上学习对作业、实验的影响几乎微乎其微。然而对于我这样的渣渣,没有大佬的线下 debug 指导,确实有点难顶。
7. 完结撒花
最后的最后,引用诸彤宇老师的一段话:“我们 OO 课就是这样一步一步让你从一个渣渣,只经过三个月,一跃成为大神的种子(然而很惭愧,由于个人的原因,本人并没有达到)。这个期间你的茫然不知所措,担忧作业无效,熬夜都是物有所值的。” 感谢老师和助教这一个学期的辛苦付出,让我们学到了太多太多。衷心祝愿 OO 这门计算机学院的王牌专业课程越办越好,为更多的学生带去实用的知识、先进的思想和过硬的专业技能!