OO_Unit4

OO_Unit4

第四单元架构设计

本单元在官方包的基础上实现了一个用于解析类图、状态图和顺序图的UML解析器,而UML图的设计规范其实已经给出了本单元的架构设计,即为每种元素单独建立类来维护,并根据UML规范维护这些元素之间的关系。

然而,考虑到本单元的查询指令受限于篇幅,又要尽量覆盖各个元素,因而对UML图的查询大都停留在较浅的层次。所以,对一些边缘化的元素而言,如UMLAttribute、UMLParameter这些元素,仅需在解析时作为枝干元素的附属即可,并没有必要单独建立类来维护。

此外,考虑到输入数据是乱序的,在解析时就需要进行多轮解析,按元素所处的层次进行分批处理,这样自底向上的设计也使得迭代过程变得十分简单——只需要判断新加需求的逻辑层次,然后在对应的解析轮次内添加相应代码即可。

最后,本单元的输入形式决定了我们需要处理的是一个静态图,而非第三单元那种会实时变化的动态图,所以提前将所有查询结果保存下来,可以避免查询时的重复计算,虽然数据规模的限制使这个策略没什么必要性。

关于OO的架构设计思路

从寒假的训练内容开始,我首次接触了面向对象编程,也顺带学习了一些简单的Java语法。不得不说这种对着题干描述的物品实现其功能的过程十分贴合类和方法的关系,体验十分不错。

相较于寒假训练内容而言,第一单元的表达式解析显得十分抽象,这是因为它使用递归下降的方法,一方面要考虑抽象层次的架构设计,另一方面在写代码的过程中又难免陷入了面向过程程序设计的细节泥潭。所以哪怕是现在,我仍认为第一单元前两次作业是整个OO课程中最难的部分。

传说中最难的第二单元电梯月其实并不难,指导书没有谜语,作业是非常直白的暴力模拟,对着指导书按部就班地使用课程组给出的电梯调度策略性能分一样不低。这一单元架构设计的重点不在难度与其复杂性上,而在理解各种多线程设计模式并进行灵活应用,比如生产者消费者模式、工厂模式、单例模式,仔细理解后会发现许多设计模式都有它的精巧结构。

三四单元其实不需要自己再去进行架构设计了,这两个单元都给出了官方包,而想要完成作业就得实现官方包中的抽象类或接口,最完整的架构其实就是把官方包的类复刻一遍(如果有必要的话)。当然,

如何进行测试

OO课程的中测数据强度严重不足,部分作业甚至无法做到所有指令的基本覆盖。因此,在每个单元都得自己写评测机与测试数据来保证强测平安度过。

第一单元的评测机借鉴了写作业时的思路,也使用了递归下降的方法进行数据生成,最后使用Python的sympy库进行正确性检验,一门课既学Java又学Python。

第二单元就没有搭建评测机了,一方面是因为多线程的输出顺序与调度策略的不一致,另一方面是电梯运行的输出量过大,难以对乘客进行追踪,即使发现了bug也难以重现/定位。所以第二单元仅构造了一些简单数据以覆盖所有基本情况,就足以保证电梯系统的正确性了,虽然最后超时了一个在最后时刻进行数十条数据轰炸的测试点,但这也是调度策略的问题,与正确性无关。

第三四两个单元之所以给出了官方包作为基础,很大程度是因为它们自身的系统较为庞大,像第一单元那样基于逻辑层次进行统一的数据生成较为困难,至少写个随机生成数据器要简单得多。同理,无法基于逻辑层次进行数据生成,就一样无法自动生成其标准答案,考虑到它们也不像第二单元有输出的随机性,于是对拍就成为性价比最高的方案了。除去随机生成数据,手动构造一些完全图之类的边界情况来测试性能,也大大减小了在强测中超时的可能性。

其实,一个学期的测试做下来,会发现真正意义上的bug其实并没有那么多。测试发现的错误,大多是某个正常的流程没有跑通,随机生成的成千上万行的数据与手动构造的寥寥数行的简单数据可以测出一样的bug。如果在写代码时就将可能遇到的情景逐个罗列出来,构造数据时进行简单的排列组合以实现全覆盖,就大可不必写评测机了。

课程收获与改进建议

OO课程给我带来的最大收获是让我学会了在短时间内设计并实现一个较为复杂的系统。

从整体架构上来说,虽然老师和同学们总是强调在写代码前进行整体规划设计,实现起来就能得心应手,我也承认这种自顶向下的架构方式有时可以免去不少无用功,也可以让写代码时胸有成竹。因此,在设计完架构后,写代码就变得十分枯燥了——按照设计按部就班地填写即可,毫无生气可言。相比之下,我个人更喜欢自底向上进行编码,写代码前速览一遍指导书,知道自己要实现哪些模块便开始动手,写代码时将精力集中于正在撰写的模块与其他模块的关系以及该模块需要实现的功能,最后将所有模块整合起来。如果说最终的代码是一幅图画,这两种做法就分别对应绘画和拼图,前者更考验整体设计水平,后者更考验逻辑思维与推理能力。

从细节上来说,设计一个复杂的系统,其内部必然有许多进行顶层设计时观察不到的精巧的小结构。我的收获主要来自同期的OS课程与OO课的设计模式。从OS课程的信号量与PV操作到OO课程中的锁,从工厂模式联想到CO的流水线结构以及有限状态机,从OS缓存结构中的脏位与修改位到OO后两个单元的查询策略(虽然这种工程化的设计思路在OO课程中几乎没有作用),OO给了我实现许多在OS课程中没能实现的结构的机会,也让我将之前只在理论上学过的一些结构应用在了实践中。

最后,我对OO课程有三点改进建议如下:

  1. 迭代时的实验指导书太长,仅用黑体或斜体标记新增内容并不明显,我相信额外给一个仅包含新增内容的迭代指导书哪怕一个单独的只罗列版本更新内容的指导书,课程体验会更好。

  2. 给出所有中测测试点信息及时整理微信群中的bug信息,讨论区发帖得到回复的时间间隔过长,问问题的即时性远不如在课程群内问问题,可以考虑建议共享文档由专人整理同学们出现过的bug,其实还是直接给出所有中测测试点信息更加简单粗暴。

  3. 不同单元以及同一单元内不同作业的难度十分不平衡(目前最难的作业要花费十数个小时,最简单的只需一两个小时)。建议要么在设计迭代任务时尽量摊平难度,要么在开课初期量化每次作业的难度系数和预计平均作业时间,便于学生进行整个学期的时间安排(其他科目的大作业、实验、课堂展示、实验报告)。

posted @ 2022-06-28 10:17  抹茶印象  阅读(15)  评论(1编辑  收藏  举报