BUAAOO_第四单元总结与反思
作者:互联网
BUAAOO_第四单元总结与反思
题目简要回顾:UML图解析器
第一次作业 (UML类图解析)
第二次作业 (UML时序图、状态迁移图解析)
第三次作业 (UML图有效性检查)
第四单元架构介绍
本单元目标是建造一个UML图解析器,并对其进行查错及各种查询指令操作。
第一次作业
UML图:
-
框架
-
第一次作业仅包含UML类图解析,核心思路是考虑将一些如类、方法等相关联内容较复杂的元素单独提取出来,自己构建类进行管理,实现层次化结构。
-
-
体现构思之处在于:
-
输入时要考虑输入的先后顺序,笔者采用了将所有元素先全部输入进来,再按逻辑层次对其进行分步输入,以使得程序可以适应任意顺序的实体输入。
-
将宏观元素管理提取出来在SearchEngine类中进行管理,使层次化结构更加分明;该类采用单例模式,查询操作在其中进行。
-
-
难点:
-
本次作业难点首先在于对于UML类图的理解,以及对于各查询指令细节之处的把握与理解,点较多、且零碎,多采用先大体构思完成程序、进而根据实例以及期望结果debug的方式,否则应接不暇的碎点容易导致编程迟迟得不到成果而身心俱疲。
-
其次,其中getImplementedInterfaces的递归查询的效能问题是本单元一个核心性能卡点。笔者采用了缓存的解决方式:在每个类中设置
bufList
域,第一次对其进行递归查询、获得实现接口序列后,将其缓存在该类的bufList
中,再次查询则无序重复递归,大大节省时间。
-
第二次作业
UML图:
-
框架
第二次作业新添加时序图与状态迁移图,框架上第二次作业延续了第一次作业的框架,在其基础上对类进行了补充。
-
构思之出:
本次实现了官方包的三个接口将其搁置在
MyUmlGeneration
与SearchEngine
间,使层次化结构更加美观易维护。 -
难点:
-
本次作业难点首先依然在理清各UML图元素的逻辑层次与归属关系,在理解掌握的基础上才能做到流畅地写出程序。
-
其次,难点在于
getSubsequentStateCount
指令,对其后状态的递归查询是性能卡点,笔者采用了与第一次作业类似的方式添加了缓存。需要注意的是状态迁移可能会出现循环迁移,需要适当调整递归过程与保存序列。
-
第三次作业
UML图:
-
框架
本单元作业在输入结束后自动进行检查,框架基本沿用了第二次作业的框架,对类的方法进行了适当补充。
-
构思之处
添加了枚举
StateType
,使层次化结构更好。 -
难点
本单元难度较前两次作业理解性门槛不高,但实现上稍难,特别是前四个查错指令,需要进行大量递归操作,而且其特性决定了其不能使用缓存,笔者只在其中一个指令中采用了缓存模式;另外,在查询是否存在重复继承的check中进行适当简化,如假设遍历到的某个接口其继承的接口有重复继承,那么则本接口同样存在重复继承,无需继续遍历。
Bug
第一次作业
第一次作业由于细节太多,导致错漏,强测产生如下bug:
-
getImplementedInterfaces
和getAssociatedClassList
两个方法均需要递归向父类寻找,原来的方式未考虑重复比如父类与子类与同一个类对象等问题导致关联、接口的重复罗列。因而更改只传名字的方法,子类记录
id
,传到MyClass
中的对应方法后,进行id
比较决定是否加入新List
,最后将新List
根据SearchEngine
中的对应更新为名字。 -
getAttributeCount
的向上深入循环有问题,多加了一层会导致NullPointerException
。 -
getAttrType
中当对应变量为RefType
,只考虑它是类,未考虑RefType
是接口的情况。 -
Operation
记录是否有重复方法时,在参数还未输进来的时候,就对其参数进行比较分配,答案有误;更改为在全部输入后统一更新。 -
getAttributesNotHidden
向上寻找时,未更新寻找父类的attributesNotHidden
,一直寻找本类的,导致错误。 -
Operation
中存储参数的Map原本设置是名字对应重复次数,但返回时只返回了KeySet
,导致每个重复只记了一次;修改:不需要map
,直接将map修改为List<String>
即可。 -
getImplementedInterfaces
性能问题。
第二次作业
第二次作业强测并未产生bug。
架构设计及OO方法理解的演进
第一单元之所以普遍感受难度最高,一方面是由于第一次接触面向对象设计思想,而更重要的则是因为第一单元对于面向对象思想体现及其充分,如果架构不好、并没有体会面向对象真正的设计思想,则会拥有极致的痛苦编程体验。一个实际化的应用场景,求导工具的实现,其中如何构思类的设计、架构建立的过程真正需要同学们自行实现设计。将不同层次的对象如表达式、项、数字符号等及其属性与功能封装成特定的类,并将类有机地整合在一起,是第一单元的重点,也让架构失败的我印象深刻,自此架构一词在我心中的分量大大加重了。
第二单元同样难度很高,其核心在于对于多线程的理解与实现,是多线程程序架构的典型范例。不同调度模式如集中式调度与分布式调度对于程序的不同影响,如何在架构上安全地实现自己的电梯调度算法都是需要考虑的核心问题。可以说如果第一单元更多的是类架构的体现,那么第二单元就是时序架构的体现。如何构造架构使得程序时序结构也达到优化,也是不可回避的问题。
第三单元难度较低,单坑点较多,是对于JML的理解与应用。根据JML完善程序几乎没有自己进行架构设计的空间,更多的是对于JAVA工程化方法的深入体会。更多的是卡性能、在限制的基础上进行优化。
第四单元难度中等,实现UML解析器主要目的在于理解UML图的构造与意义,而非实现。实现的架构上很简单,因为几乎天然地存在类的划分,即各层次UML元素,另外难点在于性能优化方法。但对UML图的掌握是对于同学们更进一步理解面向对象程序的关键。
四个单元中测试理解与实践的演进
第一单元主要采用手动构造数据样例+python自动评测机的方法对程序进行测试,该单元隶属于普通的静态测试,每一个特定数据点都会对应一个固定的输出结果。
第二单元主要采用手动构造边界数据样例的方式,构造过程较为复杂,因为同时增加了一个数据复杂性维度即时间。相同的数据,不同指令在不同的时间输入对应不同的数据结果,并且相同的数据,每条指令输入时间相同的情况下,由于多线程程序执行次序的不确定性,也可能产生不同的结果。因此发现bug构造数据的过程较为复杂。
第三单元主要采用Junit测试,该测试方式保证程序在进入某方法前的前提条件以及离开方法后的环境与给定一致,很符合JML单元的测试需求。
第四单元主要采用手动构造数据样例的方式,鉴于本单元的特殊性,构造的过程需要辅助UML图,更加直观。总而言之,手动构造数据+恰当运用测试工具,具体情况具体分析。
课程收获
本学期的OO课程收获有很多,主要可以分为:
-
JAVA语言能力:JAVA是本课的开始的前提,几乎约等于从零开始自学了JAVA语法,但在日渐的实践中自然而然也就学会了,看来对于计算机专业的同学来说学会一门语言也并非难事...逼也逼出来了。
-
面向对象的工程化编程能力:这个能力是超越JAVA以外的,适用于日后软件开发的基础核心能力,也是本课所学到的核心内容,从静态架构到时序架构,以及多线程的处理、JML的规格理解书写、UML图的绘制,极大地强化了我们的工程化编程能力。另外综合上checkstyle一学期来的胁迫,想必日后我们书写出来的代码也是赏心悦目的。
-
附加能力:许多附加的日后必备能力,如git的使用、idea的使用、md的熟练运用等
三个具体改进建议
课程的整体安排想想还是很合理的,第一单元先来一个下马威让大家深刻体会架构的重要性,不延续面向过程的编程思维,再到时序架构,再到后来的修修补补,使整个课程框架趋于完整和清晰。
其实同学们呼声比较大的可能正是在第一单元难度过大,很容易击垮信心,相比之下后续单元难度又偏简单。主要是因为,大家在刚开始阶段尚未耳濡目染体会到面向对象的思想,也不理解架构是何物,这些并非两节理论课能够说清,是需要难度循序渐进的实践中才能掌握的(对于大部分同学)。或许将第四单元调整到第一单元(其他单元顺延),让大家先通过难度不高的实践对于UML图有深入理解,之后再进行第一单元可能同学们就能够更多地体会架构的思想并加以运用了。
难度逻辑递进不够明显,大概是本课目前设计上的一个最大的问题。但当然,我明白老师们设计课程上大概还有许多其他苦衷,这仅仅是一个可能的改进方向。
其他的都很不错啦,从实践到写博客总结,能看得出课程组的老师们在课程上花了不少心思来逐年完善,这相比隔壁某4+学分课程已经要好处很多了。在此感谢老师和助教们一学期来的付出,希望我也能够无愧于这一学期来的共同努力,日后回忆起OO课永远是虽苦涩但美好的。
标签:架构,难度,作业,理解,BUAAOO,反思,UML,单元 来源: https://www.cnblogs.com/peppermint1113/p/14934024.html