BUAA-OO-第四次作业-认识UML
进入烤漆,伴随着我们一学期的OO课也进入了尾声。
一、作业架构设计
在第一次作业中,我们需要依据官方提供的解析包,完成一个UML解析程序,具体架构如下
在MyUmlInteraction类的构造方法中,完成对于不同类型UMLELEMENT的建图工作,即对于MyUmlClass类和M有UmlInterface类构建继承关系图,并将属于他们的attribute,operation以及association存储在各自的类中,以实现作业需要的查询指令,具体UML关系图如下
对于需要找出一个类所有父类的查询指令,由于在MyUmlClass中已经保存了属于自己的继承关系,通过带标记的递归即可找出其所有父类,并且复杂度有所保障。而对于只针对类自身的查询指令,统计自身属性即可。
本单元两次作业之间的继承关系十分明显,因此我在第二次作业中直接沿用了第一次作业的代码。
第二次作业相比第一次作业多出来关于状态图与顺序图的查询指令,以及对于类图的合法性检查,在官方包的帮助下新增查询指令的难度并不很大,第二次作业主要难点就在于类图合法性的检查。
相比第一次作业,我直接在类MyUmlGeneralInteraction中增添了相关方法,对于第一条检查规则,我在每个类中新增了namespace对象,用来保存属于这个类的每个attribute和associationend的名字,检查时直接遍历类图中所有类即可。对于第二条规则,针对类途中所有interface及其之间的继承关系建图,而后对每个点进行一次DFS判断有无环即可。对于第三条规则,由于第一次作业中已经实现找出一个类所有父类的方法,在此只要判断有无重复即可。
与第一次作业相比程序UML类图几乎没有变化,只是为了实现新增指令新建了几个类而已,故在此不放出第二次作业UML类图。
二、在四个单元中架构设计及OO方法理解的演进
在经历了四个单元的OO学习之后,自己对于OO设计规格以及架构也有了一个新的理解。
在第一单元多项式求导的三次作业中,主要任务是将自己在大一养成习惯的面向过程的思维方式转换为面向对象的思维方式,这个过程伴随了整个第一单元的三次作业。在第一次作业中,自己当时的面向过程思维仍然切换不过来,整个程序就只有一个类,编写各个方法时的思维仍旧是C语言写函数的思维。在第二次作业中,自己开始尝试着写多个类以降低类与类之间的耦合,降低每个方法的复杂度。本以为自己算是渐渐在了解面向对象,第三次作业就给了我一个下马威,第二次作业中为第三次作业做的准备完全没用上,依然是重构了自己的代码,并且为了在递归时没能拆分各个类型的多项式,导致自己对于性能分的优化完全没有下手之处,也意识到自己对于面向对象的理解还很浅薄。
第二单元的主题是多线程编程,在这三次作业中我渐渐体会到了面向对象的特性,降低耦合,让每个类只负责自己应该去负责的东西,以这三次的电梯调度作业来说,每个电梯只需要去管调度器分配给自己的任务,然后去执行就可以了,不需要管任务是谁发出的、怎样执行更好等等;而对于调度器来说,它需要负责一个请求应该怎样拆分、分配给哪一步电梯等等。这样解耦之后程序的架构更加清晰。但仍然存在的问题是部分方法仍然复杂度过高,以及对于多线程的理解仍旧不够,导致程序中出现过思索问题。
第三单元的主题是JML规格的理解,在官方给出的JML规格之上完成了地铁线路规划问题。对于面向对象来说,很大的一个优点就是方便多人之间的任务写作,这时JML将是一个很好的程序员统一设计规格的工具。我们需要保证类中每个方法的实现都完全符合JML语言逻辑,并将程序复杂度降到最低。第三单元中我们在架构的基础之上开始考虑合适的容器、算法的搭配,对于复杂度的计算以及算法的使用。我觉得第三章最重要的意义就是告诉我们这些看起来不太OO的东西在OO中仍旧不能丢弃。
第四单元的主题是UML图的解析,这个单元虽然只有两次作业,但代码量依旧不小,主要是以作业的形式帮助大家理解了UML图的结构。第一次看到指导书的时候我也是完全不懂指导书在说些什么,只有当自己亲自动手画了图、解析了图之后才能理解,并且这个单元作业中一个很大的优点就是帮助大家理清了最基本的架构,既跟着java语言的思路建立架构(具体可参考上文)。自己也亲手经历了数据封装的过程,回归了OO最本质最基础的东西。
四个单元的作业说少肯定是不少,但要说完成这四个单元就掌握了OO的设计思路与方法那肯定也是天方夜谭,只能说自己对于程序的理解是在不断变化的,也在不断追求着更好的架构。
三、总结自己在四个单元中测试理解与实践的演进
在第一个单元中自己还没有掌握对拍测试的方法,大都是在检查代码逻辑的基础上根据指导书自己构造一些边界测试点手动进行测试。
但到了第二单元由于多线程程序的不确定性,自己开始用python随机生成测试点并进行大量测试,这样的测试方法也一直贯穿了自己的第二第三次作业。对于第三次作业来说,由于对于时间复杂度的要求还需要我们自己对程序进行压力测试,计算程序运行所需时间以及程序复杂度。但这也是不够的,从第三次作业开始助教一直在强调对于代码的精确覆盖测试,因为大量的数据也有可能只跑了部分程序代码,而只有精确到指令的测试才能帮助我们无死角的发现问题,这也是我一直没有做到的地方,而第三次作业强测中所反映的问题也暴露了这一点(一行代码导致的强测爆炸)。
在第四单元中由于测试需要自己画出UML图,测试方法再次回归人工测试,但主要还是对于代码逻辑性的检察配合上合适的测试样例。与第一次作业相比,都是在对千行左右的代码进行逻辑检查,但检查难度差别相当大,第一单元中每个方法实现的功能都相当复杂(尤其第三次作业中的递归方法),且代码耦合程度很高;但第四次作业每个类的每个方法都有自己清晰的职能,检查起来方便很多,这也是OO思想带给我们的福利。
四、总结自己的课程收获
现在一学期的OO课程已经结束了,仔细想想这门课带给我们的不光是代码技巧的提高,更重要的是解决问题的思想方式与抵抗压力的能力。这学期的OO课程作业,每周五指导书一放出我就会立即查看,理清自己的代码架构设计与实现方法,周五晚上马原课结束后我基本就会开始实现代码,而代码这种东西一旦被打断思路就很难在续上,因此每周五熬夜码代码几乎成了我这学期的一个固定项目。而到周三开始互测后,又开始隔两个小时刷一下网页来看看有没有被狼人hack,互测结束后很快就是下一次作业的开始。个人感觉,这种充满压力的生活方式就是OO课带给我们的财富。
当然,对于继承接口多态的理解、自动化测试技能的掌握、千行左右代码的调式能力与设计能力、辅助工具的使用、多线程的理解、UML的熟悉、面向对象的思想也都会一直伴随着我们。
五、课程的三点建议
第一,个人感觉对于一门课程的体验来说,规范性是相当重要的一点,因此希望课程组在每次指导书发放以后,尽量减少改动的次数,无论是测试数据的要求亦或是功能实现方面,将讨论区中同学们发现的问题更多的提前规定在指导书当中。
第二,对于每个单元中三次作业的难度我们可以清晰的看到递进关系,但这种关系在单元与单元之间却并不明显,第一单元的第三次作业已经相当考验同学们的代码能力以及架构能力,这种难度增加曲线个人稍显陡峭。
第三,可以适当增加中测难度,尤其第三单元中,中测与弱测几乎没什么区别,但相比与强测而言几乎是一个天上一个地下。
OO这门课如果认真学习真的可以得到相当多的代码开发设计经验,也真心希望这门课越来越好。