OO第四单元总结

OO第四单元总结

本单元架构设计

任务概要

本单元作业要求补全一个UML解析器,实现对UML图相关信息的整合与查询,以及部分规则的规范性验证。具体为第十三次作业实现UML类图相关指令,第十四次作业实现UML顺序图和状态图的相关指令,第十五次实现部分规则的规范性验证。

值得注意的是,本单元的官方包已经为你完成了对于输入数据的预处理,将其整理为UmlElement数组传递给你,需要完成的任务可分为以下三部步:

  • 识别传入的UmlElement的具体类型

  • 将对应类型的数据存储到构造好的容器中用于查询,以及完成一定的预处理

  • 根据要求实现相关指令

输入架构

Uml图的元素间有着一定的依赖、上下级关系,在输入的过程中以合适的顺序分批对不同种类的元素进行存储,可以保证关联的对象已经存在,从而正确的构建存储模型,避免出现需要的对象还未载入的情况。

输入顺序的安排可通过Uml元素间的关系来排布,主要有父子关系,以及source、target等索引关系,笔者的处理流程由下图展示,输入架构一共分五轮,顺序为从左往右,保证了输入时的依赖与索引关系。

 

存储架构

本单元的作业核心就在于对于数据的存储,笔者构建MyUml***类,将原有的Uml变量与自建的容器相结合结合,并在其中添加为实现指令要求所需要的方法,并在“作业顶层”MyImplementation中用容器存储这些类,用于指令函数中进行查询与调用相关方法。

其中,笔者选用的容器为HashMap和HashSet。因为题目限定了UmlElement的id唯一,因此以各自id为Key,对象为value十分好用;而HashSet自带去重功能,某些指令需要完成字符串去重,使用HashSet就直接完成了这一要求。

记忆化

值得一提的是,本单元的题目具有一次构造,多次查询的特点,因此笔者采用了记忆化的特点以提升程序性能,具体操作时给待查询的量设置一个标志位,判断其是否以为计算得到,若未则进一步进行计算,否则直接返回已存储下的值。

迭代模块化设计

本单元的三次作业间界限分明,因此可以将每次作业的新增指令或Rule封装成一个模块来进行管控(其实还有一个考虑就是CheckStyle限制了一个类的篇幅,难以在MyImplementation类中完成所有指令的主体部分。就第三次作业来说,笔者用单例模式新建了MyRule类,里面存储了相关Rule有无违反的标志位以及部分检测过程,同时由于单例模式,让各类都可以便捷地访问该类并进行Rule违反的标志。而在具体的checkForUml00*的用户接口中,只需查询对应的标志位抛出异常即可。

部分细节

NotFound & Duplicated 异常

这两个异常在大部分指令中都需要考虑,笔者实现方式是遍历一遍对应容器,用count记录满足要求的个数,如若最终count为0则是NotFoundException,count大于1就是DuplicatedException。我们可以将这一过程封装成专门的方法,可以有效降低程序的复杂度。

Rule003 循环继承检查

该规则的检查可以使用dfs或者类Floyd最短路的算法,笔者采用的是后者,即将最短路中的路径长度改为两者是否连同,执行一遍Floyd算法后,若某类或接口自己和自己联通则说明其发生了循环继承。

注意使用一般的拓扑序列无法实现该检查,因为数据中可能出现自己继承自己的情况,即出现自环。如下述情况,可能会导致错把也当作循环继承的一份子。

 

单元总结

通过本单元的学习,我对UML图有了十分深入的理解,同时在容器选取、数据架构、数据交互等方面都得到了很好的锻炼,同时程序设计更趋于模块化,整体架构更加清晰明确,写代码能力进一步提升,收获巨大。

架构设计思维及OO方法理解的演进

第一单元——表达式解析

刚接触面向对象,我凭着大一经验,在Main函数中直接实现了第一次作业,完成了一个面向过程的程序,觉得挺简单的自信满满。但是第二次作业出现的三角函数立马就打脸了,多项东西的嵌套使得面向过程的实现异常艰难,我开始真正接触面向对象,并且最终构造出了多项式-项-基元-多项式的循环嵌套模型,初步理解了面向对象的巧妙所在,同时也体会到了其中的封装性,算是入门了面向对象。

第二单元——电梯调度系统

第二单元是第一次接触到多线程编程,其中最关键的是线程间的交互与安全问题。经过三次作业迭代,在学习了诸多面向对象程序架构后,我采用了生产者-消费者模式,设计了InputThread输入线程-Schedule调度线程-Elevator处理线程的电梯调度系统,分别实现了输入处理、任务发布和任务实现的三个部分,并在实现过程中是用了synchronized和读写锁`的方式来保证线程安全。

在这个单元中,我学习了面向对象对于资源的分配以及共享,对不同对象间的交互与安全有了更深的理解。同时,在设计不同的电梯与不同场景下的功能,体会到了面向对象继承性和多态性的意义所在,正确的面向对象性质利用可以降低程序的耦合性,极大提升程序的效率。

第三单元——JML规格训练之社交网络模拟

这一单元训练的是JML语言的阅读以及将其实现为代码的能力。除了每次作业中的简单图论问题,基本上没有思考的难度,重点在于如何规范地、简洁的实现规格的要求。

总得来说这一单元的架构较为清晰简单,主要就是实现规格要求的几个My***类,在类中选用HashMap等合适的容器存储相关信息以及实现类间的关联,最后根据信息和一定的算法完成指令即可。但值得注意的是,在具体实现过程中,要做好预处理与记忆化,不然可能会因此出现超时的情况。

虽然这单元实现起来较为简单,但我认为对我个人编码能力的提升是很有作用的,主要体现在代码规范性这一点上。因为JML已给出了规格,在编码的过程中,我会更加注重实现过程是否清晰明了、有无繁杂重复,旨在让自己的代码具有高效率、可读性高的特点。以此要求自己,我发现写代码的过程中思绪清晰,且事后证明程序出现的功能性错误也较少,因此我深刻认识到了代码规格性以及简洁性之重要,在日后我也会继续这样要求自己。

第四单元——UML图解析

第四单元简单来说就是要实现对UML图的解析,提取其中的信息并完成一些查询指令,其架构在本总结开头就是阐明,就不在此赘述了。

在前几个单元我对于UML图一直缺乏理解,一直都是为了完成任务得过且过,而这个单元最大的收获我觉得就是对于UML图有的一个系统、清晰的认识,总算是真正掌握了其原理与实现。除此之外,这一单元需要存储的信息量很大,如何用较少的类和容器实现题目要求的指令是一个关键问题,在不断规整和设计的过程中,我对这一方面也有了更深的理解。

测试理解与实践的演进

随着四个单元的不断训练,我对于代码的测试愈发熟练且习以为常。

第一单元

第一个单元我对于测试还没有什么清晰的认知,认为只要能通过网站的测试就是ok了,并没有对自己程序的正确性有很好的“责任感”。数据也仅仅是随意捏造一些简单的小数据,希冀sin(0)之类的数据可以hack到别人优化的错误,没有很好地检查自己程序的正确性,在第二次作业三角函数的处理中出现了错误。

第二单元

第二单元的背景是实现一个电梯调度系统,具有现实意义,我认识到对于程序的测试和完成程序应是不可分割的,要及时检验这样才能减少交付使用后可能出现的问题,这是我们程序员的责任,要尽量做到对程序的全面性测试,充分考虑到将来程序使用中的各种情况与场景。构造数据时,我往往会设计一个背景来有针对性地进行测试,注重于对某个部件或功能的检验,以及多部份间协作可能导致的错误。例如在第三次作业的横向电梯中,我就设计了诸多横向的请求,以求的横向电梯可达性实现部分进行检测。

第三单元&第四单元

后两个单元相较于前两个单元,规范性较强,简单的数据不容易查出问题且手动造数据较为困难,同时我还意识到程序所经历的场景是复杂多变的,有时候单凭人手很难有一个较为全面的测试,需要通过测试机通过随机和大量来提升测试的效果。因此我开始接触自动测试,尝试写了一个测试机,可以实现通过jar包运行大量数据得到结果并且自动对不同的结果进行对拍,反馈出有差异的数据点,进而再通过具体的数据点去发现问题,极大提升了程序检测的效率。

比较可惜的就是我本人并没有自主实现一个数据生成器,在随机产生数据这一方面的能力还有所缺陷,在接下来我也会学习去尝试这方面的实现逻辑,并希望以后在还有机会的时候能自己完成一个数据生成器。

OO课程收获

面向对象概念

通过四个单元的学习,对面向对象的理解与实现逐步加深,在写代码过程中不断领会到封装性、继承性、多态性的优势所在,熟练掌握了面向对象的编码方式。同时,拥有了面向对象的思考角度,面对问题时能够尝试将其细分,从对象的角度出发,合理规划信息的存储以其功能的实现。

线程交互与安全

第二单元中接触到了全新的线程知识,掌握了线程的创建、交互以及锁的使用,同时了学习了多种模型与单例模式、生产者-消费者模式等,对于我的编程理念来说一个跨越式的提升。

程序测试

认识到了程序测试的重要性,同时也制造数据和检验程序的能力也得到了有效锻炼。从一开始的随随便便造点数据应付一下,到后来的专门测试且初步造了一个检测机,可谓是在程序测试能力方面有了一个全面的提升。

代码习惯

一方面,在于CheckStyle斗智斗勇的过程中,渐渐有了规范化的编码习惯,经历一个学期后写出的代码明显变得更加简洁优美;另一方面,通过根据规格要求的代码训练,对代码规范性有了全新的认识,在写代码过程中注重代码的规范与可读性,不再会写出原来繁杂冗余的代码。

总结

至此OO的课程就暂告一段落了,总得来说OO是一门综合性强、知识量丰富的课程,其训练模式让同学们在加深知识理解的过程中,也锻炼了代码的编写与检查能力,即使如此也不感枯燥,是一门十分成功的课程。在这门课的学习中,我收获良多,在此再次感谢老师与助教们的悉心教导与付出。

一些课程改进建议

关于课程内容

  • UML图的内容可以早一些系统地讲讲。第一第二单元的博客作业都有明确要求对UML图的制作,但是早期未曾系统学习,导致有些茫然无措,我认为早一些对UML进行一定的系统教学有助于在制图中更好地理解其规则与意义。

  • 个人认为研讨课的主题可以再修改一下,虽然这学期的研讨课都给出了几个主题供大家选择,但是最后因为同学们大多都没准备而选择了叙述本单元作业实现的主题,导致最后的内容分享就是十个组上台讲述基本相同的内容,个人感觉意义不大。一种可能的建议是不要设置这种分享作业实现方式的研讨主题,而是限定一些任务量小的探究型主题,可以让同学们有更多的收获。

关于作业与指导书

  • 建议可以给每次作业的指导书适当加上目录索引,方便做题时快速查看要求。

  • 第四单元指导书的内容有些冗余,特别是迭代至第三次作业可以发现大部分的内容其实并无改动,只是罗列前两次作业的要求,导致信息检索与获取有些困难,建议指导书可以将前两次的内容用链接指向之前的指导书,而在新的指导书中只给出本次的新增内容,以及罗列出有改动的部分即可。

  • 在OO作业的完成过程中,本人经常的一个操作就是翻阅微信群中的大量消息,从而找寻可能的出错情况。建议可以在OO网站中给每次作业开设一个“错误分享区”,鼓励同学们在该区给出自己遇见的错误以及解决方式,再进一步可以给出一定的对设计的思考,给同学们一个更好的做作业体验,也降低了助教在微信群中的答疑压力。另外建议可以实现答疑贴中在问题下直接回复,而不是在后面使用@来进行回复,一定程度上可以提升网站使用的观感。

posted @ 2022-06-29 18:28  kingimtk  阅读(28)  评论(0编辑  收藏  举报