面向对象编程学期总结
一、总结本单元两次作业的架构设计
单元概述:
本单元介绍了UML类图的知识与用法,并且通过StarUml软件来生成相应的UML垒土、状态图、时序图来进行相应的验证。UML语言:统一建模语言(英语:Unified Modeling Language,缩写 UML)是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。下面讲一下本单元所学到的一些理解。
第一次作业
这次作业主要是进行类图的解析。主要的思路就是从UmlClass和UmlInterface进行建立层次结构,然后根据UmlAttribute、UmlParameter以及Umlssociation等进行建模。进行两遍扫描,第一遍扫描,首先将所有的类,接口等UmlElement记录下来,第二遍扫描将所有的类、连接关系等建立起关系。本次作业的解析过程没有什么难点。主要是怕TLE的错误,因此我们的想法是将一些可以重复使用的东西存起来,方便日后查询的时候直接使用
类图
这里主要需要介绍的是
InterOrClass
这个接口,由于第一次作业涉及到了类和接口的问题,因此必须要区别这两类,但是这两类之间有很多共享的相同点,如果分成两部分来处理则会有很多的冗余操作,因此我们设计了一个InterOrClass
接口,我们使我们的UmlClass
和UmlInterface
类都实现这个接口,而在这个接口里放共同的函数这样就可以使我们的代码简单明了。
Bug分析:
本次作业未出现Bug,也是对我的理解的一种肯定。
第二次作业
第二次作业重要是在第一次作业的基础上加入了有关状态图和顺序图的分析,并且对于代码进行三种规则的验证。在状态图和顺序图的方面,总体来说逻辑还是比较清楚的,依照上次作业的方法就可以做个大概,重点还是先理解各个元素的含义,主要的难点在于类图的三个规则的验证。尤其是008和009规则的验证。首先讲008规则,由于008规则要识别所有的成环的类或接口,因此我使用了DFS的深度优先递归搜索算法,并且记录下已经遍历的节点,当识别到一个节点已经在当前路径内,则我们将成环的一些点删去。对于009规则,我们使用类似的算法,识别出重复实现的接口,并且对于这些接口,实现其的类也算做矛盾类予以删除。对于009规则存在很多种复杂的情况,讨论区已经阐明,此处不一一赘述,在构造数据集进行测试的时候,需要注意覆盖到每一种情况。
类图
这次的设计思路与建模方式与第一次作业相同,并且针对UML顺序图和UML时序图的查询也都相对比较简单,因此在解决了上述三个check规则之后就一路畅通无阻。
Bug分析:
在中测过程中,我出现的Bug是对于009规则的查询存在遗漏的情况,即
CLASSA
实现了IA
,IB
,然后IA
,IB
分别继承了同一个IC
,这样CLASSA
就是违反了009。
二、在四个单元中架构设计及OO方法理解的演进
心得
刚接触面向过程的编程的时候,心里还是挺惊慌的,因为心里还没有从面相过程的思维中转变过来,当然这样的转变也不是一朝一夕就能完成,老实来说,最后一个单元的架构中,我依然存在很多的面相过程的编码习惯,这也说明了我们还是需要一段很长时间的练习才能完全形成面相对象的思维。下面讲一下我在每个单元中的思路历程。
第一单元
该单元是进行多项式的求导,第一次作业的惨痛教训我至今难以忘记,由于第一次写代码,写的完全就是面相过程的形式,所谓的‘类’,也就是套了一个类的空壳子,里面的代码完全就是按照面相过程的形式进行的,因此在该单元第二次作业时,所有的代码都需要进行重构,这就让我下定了决心要好好理解面向对象,当时的想法就是多创建类,将类类分离,每个类各司其职,将其耦合度降低,虽然理论上都知道,但是在操作起来时还是存在很多不熟练的问题。在第三次实验,带有递归的求导时,我觉得是我真正意义上第一次比较好的使用了接口、类的含义的一次实验,我将求导与类分离,这样每个对象只关心自己的事情,因此最后的强测也比较满意。总的来说,第一个单元的几次尝试,让我初步了解了面向对象的思路以及构造之法,至于代码能力,还需要加强训练。
第二单元
第二单元的作业是有关电梯调度的作业,这次的训练核心是多线程的运用。在这三次作业中,我主要是针对当前的情况通过不同的调度算法进行调度,将电梯作为一个单独的线程。该单元我觉得是几个单元中最难的一个单元,因为多线程的理解的确有点困难,好在还是挺过来了,也收获很多。主要的思想就是建立
Elevator
,Dispatcher
,User
三个类,然后每个类完成自己的职责,并且互相联系。难点就在于如何联系,前两次我使用暴力轮询的算法,但是这样的话会导致RTL的问题,因此最后一次作业我对每一个可能会发成轮训的地方,我们都采用wait
,notify
的方法来进行解决,这样可以大大减少CPU的没必要的使用时间,大大增加了程序的执行效率。还有第三次作业中的调度策略需要进行划分,这对于类的架构设计要求就更高了,需要你明确每个类的职责,不然在多线程中就会出现很多难以描述的问题。总结,第二单元让我更加明确了类的职责,也搞明白了多线程的一些问题。
第三单元
该单元我认为是在四个单元中比较简单的一个单元,主要的目的是对JML规则进行理解,我们根据JML规则进行代码的撰写。但其实JML的规格理解还是其次,主要的提升是对于类与类的数据结构的架构设计以及时间复杂度的合理把控。因为在这次作业中我就出现了RTL的错误,因此我们必须要合理构造数据结构对数据进行存储。在第三次作业时,由于存了很多不需要的重复节点,导致时间复杂度过高,导致很多的节点时间超时让我悔恨至极,因此在第四次作业中我很认真地对算法和数据结构进行了设计。总的来说,这个部分我学到了很多关于数据结构以及查询效率方面的内容。
第四单元
见第一部分,主要收获和第三单元类似。
三、总结自己在四个单元中测试理解与实践的演进
这个单元主要阐述我对于测试数据以及实践演示的理解,在第一单元的时候我还不了解自己构建测试集的重要性,每次都是以为中测过了之后强测就稳了,殊不知好几次强测都挂了很多点,而这原因大都是因为一个很简单的小问题,而这些问题也正是由于自己没有构建测试集而造成的问题。因此从第二单元开始我就自己构建测试集,先整理好有哪些边界条件,或者可能出错的问题,然后针对这些问题一一构造数据集进行测试。针对电梯单元,我特意用python编写了测试脚本,可以模仿评测机,对输入自动解析,并且在相应的时间节点重定向入标准输入。但是还要注意有一些设计上的bug是数据集可能无法测试出来的,这些问题在多线程中是多发的,因此在设计多线程时,最主要的步骤还是在设计的时候就想清楚一切,而不要过分依赖测试集。
针对第三单元,我使用了Junit对每个方法进行了单元测试,这个好处就是你可以着眼于局部,对每一个函数检查其正确性,使测试覆盖面更加全,并且更加容易定位错误的发生位置。同时学习了OpenJml来对JML语言进行规范化的验证,同时也用Jprofile对生成的代码运行时的内存资源等进行调研。明白了JVM虚拟机在运行时的CG等机制。针对第四单元,我们学习使用StarUML对UML进行设计并验证,明确了各种图与图、类与类之间的联系。同时编写Junit单元测试真的对于接口方法实现的正确性验证起到很大的作用。
四、课程收获
1、让我的思想从面相过程向面相对象进行转化,以前难以理解或者毫无思绪的一些建模情景,现在都可以通过面相对象的思想来进行简化,这无疑是对我编程道路上的一个跨越。
2、收获了框架设计的重要性,以前编写代码都是想到什么写什么,现在经历了一系列OO实验的洗礼,深刻明白了设计的重要性,千万不要急于编码,要先把作用、规格想清楚,并且注意代码的可扩展性再进行编码。
3、类与接口的设计,类的设计越简单明了越好,每个类承担的责任越少越好,类与类之间尽量减少交集,减少耦合,这样在进行扩展的时候就能减少代码的修改。
4、对JML规格的认识,代码在编写之前,先确定接口、方法的规格,这样有助于写代码的时候明确代码的输入输出以及异常情况,这样既有助于自己的代码撰写,也有利于团队合作时其他人编写代码时的理解。
5、认识了代码风格的重要性,学会了使用pycheck,曾经在编写代码的时候,我不会顾及代码的风格,想到哪写到哪,一个函数可能写个一两百行,一个函数处理了很多的方法,每个函数显得十分臃肿,即不明确其功能,在维护或者扩展时也显得十分困难,现在每个方法的功能明确,职责分离,利于实现以及维护,同样也对阅读者比较友善,他人容易阅读代码。
6、最后就是对于测试验证的理解更加深入,以前对于测试验证的过程不够重视,草草了事,经过该学期的磨练,认识到了测试验证的重要性,毕竟以后的工作是服务于客户,为了客户的良好体验,必须要覆盖到每一种可能发生的情况,保证程序的健壮性,在任何情况下都不crash。
五、立足于自己的体会给课程提三个具体改进建议
1、对于起点难度的把控:
我觉得本学期四个单元的作业对于能力的提升确实比较大,但是可能每个单元的难度把控不是很规范,比如第一二个单元难度比较大,并且开学的时候大家对于JAVA都比较陌生,可能编码比较困难,因此我建议在课程开始之前先对JAVA的一些基础知识进行教学,或者前两个单元给比较长的时间,让我们同学有一个比较好的过渡和比较充分的了解JAVA的时间。
2、课上实验改进:
课上实验的内容的确比较结合我们的编程以及学习内容,但是每次实验之后我们的结果就石沉大海,得不到任何的反馈,甚至连自己错了,对了都不知道,并且也没有任何的讲解,我认为没有反馈的训练就比较乏力,就比如梯度下降算法也是靠反馈来优化参数,只有错了再优化我们的能力才能提升,因此我希望能够在每一次实验课后将我们的结果进行反馈,并且在理论课的时候简单地讲解一下上次实验的内容。
3、关于强测机制:
我觉得强测的时候可能过多的测试点都是有联系的,往往有些同学都是因为一个小小的错误导致一半的测试点全部错误,这样的话可能让同学会有点沮丧,并且可能因为这样而拉不开层次差距,建议以后的测试点之间的耦合性降低,使同学们的分数之间有层次感。
六:展望
本学期OO带给了我很多心得东西,也希望OO课程组能认真采取同学们的反馈,将这门课做的越来越好。