任务简介:本单元在介绍了UML中几种基本的模型图元素的基础上,通过实现课程组提供的官方接口来完成自己的UML解析器。
架构设计
本单元最终的整体架构图如下(不包括官方包):
从文件树的角度来看,或许要更加直观一些:
│ Main.java
│ MyUmlGeneralInteraction.java
│ UmlParser.java
│ # 顶层交互处理模块⬆
├─exceptions
│ NoSuchLifelineException.java
│ NoSuchOperationException.java
│ NoSuchStateException.java
│
├─myelements
│ │ MyUmlElement.java
│ │
│ ├─classdiagram # 类图元素
│ │ MyUmlAttribute.java
│ │ MyUmlClass.java
│ │ MyUmlClassifier.java
│ │ MyUmlInterface.java
│ │ MyUmlOperation.java
│ │ MyUmlParameter.java
│ │
│ ├─seqdiagram # 顺序图元素
│ │ MyUmlInteraction.java
│ │ MyUmlLifeline.java
│ │
│ └─statediagram # 状态图元素
│ MyUmlState.java
│ MyUmlStateMachine.java
│
├─parsers # 解析器
ClassParser.java
Parser.java
SeqParser.java
StateMachineParser.java
回顾这全部四个单元,到头来我竟有一种怅然若失的感觉,心里仿佛在说:”难道这样就结束了吗?“总体来看,Unit1带给我的收获应该是最大的,毕竟从模型架构、性能优化到自建评测机、组内互测,很多都是第一次,于是就觉得有点小激动,最终亲手完成后的成就感也是之后再没有体验到的了。当然,接下来的每个单元也是各有各的魅力,在第二单元里,借助多线程这个契机,我把《图解JAVA多线程设计模式》这本书从头到尾翻了一遍,也了解了很多有趣实用的模型,实际编写与测试中也对线程安全有了更深的理解;而原本看似平平无奇的Unit3,自己却突然中途翻车,这迫使使我重新开始审视测试这个先前被我一直下意识”忽略“的环节;至于最后的四单元,更多的注意力已经正式转移到了模型设计与架构上,也介绍了很多UML中的实用工具,应该说属于理论意义大于实践的一单元。
在架构设计上,事后看来,似乎我在第一单元的时候就已经是站在模型设计的角度来进行开发的了,那个时候我在第二次研讨课上分享的内容正是关于模型架构的一些思考,但与Unit4中介绍的UML相比起来,还略显稚嫩,更多地停留在具体问题具体分析的层面,不够抽象,也不够严谨全面。
接下来的Unit2,则是进入了多线程。这部分我主要使用的就是基于生产者消费者模型的中央调度器架构,对于电梯这一场景基本上也算是完全够用了。但是在理论上,自己确实接触了非常多的不同的设计模式,比如Guard,Worker等等,这些都给了我一定的启发。
至于Unit3,由于受到JML的约束,因此在总体架构上没有太大的发挥空间。但即便如此,我还是尝试把抽象的图模型与算法和顶层的社交网络交互模块相分离相解耦,以降低局部复杂度。
而在Unit4中,我则是根据不同的UML类图做了一个横向的分割,核心还是层次化
测试的理解与演进
我对于测试的理解可以说是以Unit3的第二次作业为分水岭,分成了前后两个阶段。前一阶段由于有标程的辅助(Unit2电梯可以对过程进行检查相当于标程),所以在写评测机的时候将重点放在了搭建评测机生态上,也就是怎么输入数据,怎么获取输出,怎么进行对拍这些流程化的工作,虽然看似工作量很大,但现在回过头来看,就会发现其实这部分内容写多了真的也是千篇一律,有固定模板可依的。
虽然在这一过程中,自己也考虑过对极端边界情况进行特殊检查,额外手动构造一些数据,但是主要我还是依赖于大规模随机来完成测试和debug的任务。而到了Unit3,由于有了JML的指导,因此大规模随机测试也就丧失了它存在的意义,但同时由于我缺乏对于手动构造数据的经验,因此不能很好地针对需求构建全部的相应数据来进行完整测试,虽然使用了Junit但也只是换了一形式而已。于是这就使得我在Unit3的第二次作业里没有考虑到多种查询之间的组合情况,因此忽视了自己程序的一个根本bug,并为此付出了惨痛代价。
在吸收了上次的经验教训后,现在的我比起形式上的搭建评测机,更加重视测试数据的构建,毕竟在现实中,是很难保证可以有一个标程给你对拍的。比起黑盒测试,白盒测试对于功能完备性的检查无疑要更实用些。当然,对于具体的情景,我们还是要针对具体的需求与算法来设计相应的测试数据,无法一概而论。
课程收获
OO的四个单元我认为应该是各有各的特点,并不能仅仅根据作业的难度进行判断。当然仅就难度论,1, 2单元的难度无疑是要高于3, 4单元的,当然这不排除是因为前两个单元有性能测试所以更卷的原因。
具体而言,Unit1更强调Java语言的基本特性与面向对象基本思想的初步实践,Unit2引入了多线程,需要考虑并发在时序上可能带来的新挑战;Unit3开始向理论倾斜,介绍了JML这种规格化设计语言,顺便复习了图模型的相关算法;Unit4则是引入了更抽象更一般的UML,脱离了Java的限制,更加贴近于”面向对象“这门课的核心主旨。
从这个角度来看的话,或许与一些同学所理解的不同,Unit1,2,3,4在我看来应该是逐层递进的,它在一步一步尝试脱离Java编程语言的限制,试图在一个更高更广的维度去探讨面向对象这种思想以及其背后的层次化、模型化的设计理念所能够给开发者带来的启示。当然,在这个过程中,我们也学到了很多其他东西,比如Java的许多语言特性、如何用python手写评测机、Junit单元测试等等。但是,我认为这些其实反而是这门课程的副产品,或者说是媒介。而课程的核心则正如课程名所言,强调的是”设计与构造“,是形而上的理念,是编程的艺术和灵魂。我想大概这也是我们从根本上区别于那些从速成班出来的同学的地方吧。
但思想如果没有落到实处,就终归还是一场空谈。而如何落到实处呢?我想唯有给出一系列真实的应用场景,引导我们在这些具体的场景下进行分析和思考。当然,这些场景不应止步于课件、实验与作业中,在今后的学习与工作中,我们还应该时刻贯彻这种抽象化、层次化的设计理念,将一个复杂的问题逐步解构、分割,变成一个个易于解决的子问题。我想这才是OO这门课带给我的最大收获。
改进的建议
-
-
建议提前一天发布指导书,或者至少公布课上的讨论题与相应的应用场景,让同学们先进行思考,也就是相当于预习。而不是一直等到上课前15分钟才发布所有的PPT,或者上完课后才以作业的形式发布指导书。我一直认为,带着问题思考学习绝对要比一无所知从零开始听老师讲要高效的多。
-
为什么线上的讨论就一定需要占用额外的时间呢?如果按照原有的教学设计可以在给定的课时内完成所有教学任务的话,为什么一移到线上就必须要让学生在听课的同时关注微信群里的问题呢?我觉得这样显然不合理,也容易造成讨论不够热烈的结果。按正常情况来讲,在确定录播课的时长时就应该考虑到讨论所要占用的时间,并事先将这部分时间空出来,我认为这样在不拖堂的前提下要更公平一些。
-
-
课程反馈上:
-
建议公开实验的结果。这样做,一方面可以让同学们心里有数,如果之前的实验有失误的话后面也可以及时调整;另一方面,公开透明也有助于建立客观公正的评价体系,使OO这门课程未来发展的更加健康。而且啊,公开结果不等于公开成绩,比例什么的或许可以具体问题具体分析,我认为应该不会给课程组进行最后的打分造成什么阻碍才对(当然前提是实验判分要足够客观才行)
-
-
内容设置上:
-
我不太清楚其他同学对于OO这门课的难度感受如何。我的感觉是,虽然形式上OO看起来是有些吓人(测+互测+高代码量),但仅就难度而言应该要低于CO和OS,后两者总体复杂度还是要高一些的。我想,这可能是因为CO和OS都是从头到尾的迭代式开发,难度逐渐升级,而OO每个单元则相对比较独立,复杂度的上限不可能设的太高。
所以,如果OO满足于这样一个难度定位而不想进一步增加同学们的负担的话,我认为这样的内容就很丰富了,最多也就是Unit3可能还需要再充实一些,比如用出租车抢单系统代替,然后看看能不能引入多线程这样?
如果OO还想再进一步提高难度的话,那么我认为可以仿效CO和OS,看看能不能将前三个单元进行重构,使得每个单元中的一部分内容都可以被用到下一个单元或者最后一个单元中,以提高整体项目的总复杂度。或者是将每一个板块的内容挖的更深一些,比如将前两次task合并,再多新增一次task,引入更加复杂的设计模式等。
-
实验部分的内容我认为很有必要继续加以完善,要让评分更有规范性。我记得Unit3有一次bug修复的实验,我就不是很理解这部分内容的意义,是为了让我们以后能够更好地修改前人留下的代码吗?如果是那样那我选择直接重构。同时我也不能确定这部分需要如何进行评分,难道要老师和助教肉眼检查每个程序的bug是否都完全被找到了吗?
-
-
研讨课
-
线上学习的体会
线上学习很奇妙,不仅前无古人,我想很有可能也是后无来者。
但总体上看,OO受到疫情的影响应该是最小的。毕竟OO的所有实验、作业评测本身都是在线上远程完成,但这并非就意味着没有影响。像理论课的教学,课后的讨论还有研讨课的交流,都因为线上的原因使得质量与效果有所降低。
但真要说有什么体会的话,我觉得更多的是作为一种奇妙的回忆来看吧。毕竟这样的事后面应该不太可能发生了,而我们也在经历了最初的不适应后慢慢调整并习惯了这样的一种教学模式,因此也没有感受到太多直接的不利影响(间接的就不好说了)。
不知道其他人的看法如何,在我看来,线上学习的感觉就像是自己在和自己对话,获得了最大的自由度的代价就是丧失了与他人之间的实时交互——你缺少一个可能的参考线,一切都必须要靠自己。强者在这一过程中不断超越自我,弱者在这一过程中不断迷失自我,但作为一般人的我们,则更多地是在这两种状态间上下游走不定,时而因收获而感到喜悦与自豪,时而因坎坷而感到迷茫与自疑。
但不管怎么说,最终我们还是有惊无险地走过来了,不知不觉间与其他同学还有课程组一道完成了这样一次伟大的具有里程碑意义的教学实验。也许在以后,这样的教学模式还可以进一步推广,比如如果北航和某贫困地区(不一定就是国内)建立一对一帮扶体系的话,就完全可以把这一套模式直接通过网络搬过去,在极小的人力代价下或许就能取得极高的收获。当然了,这样一个体制之所以能够成功,背后还是要依靠学生们的积极配合与高度自觉,以及一套完善健全的监督奖惩体系,后者可以借鉴,前者可就难下定论了。