程序笔记   发布时间:2022-07-20  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了OO第四单元总结大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

第四单元总结

第四单元的OO作业是要求做一个UML文本的解析器,这里先介绍一下什么是UML。

UML建模语言

UML的全称是Unified Modeling Language,意为统一建模语言,从名字上就可以看出,这种语言的设计是为了统一各个领域的建模语言。在软件领域的发展历程中,出现了许许多多的建模语言,包括面向对象程序设计等,UML是在消化、吸收、提炼至今存在的所有软件建模语言的基础上提出的,集百家之所长,它是软件建模语言的集大成者。

上面对UML的介绍可能让读者依然对UML是什么感到疑惑,事实上,在软件设计领域的许多方面都存在着花样繁多的模型,如工作模式中存在瀑布模型,还有项目中的对实际需求抽象得来的模型,如银行的现金存取系统就可以抽象成一系列的流程进而用UML表示出来。UML的意义不仅仅在于提供一种表示静态模型的规范,也在于精确描述动态模型的运行过程。举例来说,Java这种面向对象的语言为我们提供了各种对事物的性质进行抽象的方法,如类,基类,接口,继承和多态等等,但是这只是一个静态的语法和思维方式,而现实世界中的许多过程还涉及到动态的变化,这时候UML语言便为我们提供包括顺序图,时序图在内各种描述方法,为建立一个动态模型提供了强大的工具特性。

本单元的代码架构

官方库介绍

尽管本单元的输入都是从StarUML中导出的UML文本,但是课程组已经为我们做好了初步的处理,那就是从输入中提取出基本的信息并实例化相应的UmlElement对象,UmlElement这个类代表UML建模中最基本的元素,而各种类,如下图中的Door♂,Client甚至它们之间的继承、泛化关系都被视为一个UMLElement,当然,为了更进一步表示它们,官方代码库里还提供了更多继承UMLElement的类,如UMLClass、UMLGeneralization等等,总之,我们的任务就是对读入的所用UmlElement对象进行解析,按照UML语言的规范建立起它们的抽象关系,并在第三次作业时加入规范性检查。

OO第四单元总结

第一次作业架构

做第一次作业的时候我对官方库干了什么一无所知,于是对自己要干什么也毫无头绪,于是我遵从迭代开发(其实就是走一步看一步)的原则,没有进行架构设计而直接开始实现接口中的各个方法,写到最后我渐渐明白了官方库和这次作业究竟需要我们干什么,但为时已晚,我已写下一个将近500行类(shi shan),没有额外去定义任何的类,由于公测时间即将结束,我过了公测就没有再去重构代码。

代码中的数据结构如下:

OO第四单元总结

可以看出由于没有对UmlClass进行抽象,把同一个UmlClass下的信息(如类的属性、方法等)进行聚合,导致它们分散开来,变成了多个二重哈希表。这种架构有优点,那就是面向过程编程的优点—写起来快,直观,无需过多设计步骤。因此,它的缺点也就很明显了,抽象性不高,debug和测试困难,代码扩展起来十分不便,写代码的欲望和代码长度成反比。

该次作业出现的bug有三个,它们是忽略了接口可以继承多个父类、输出类中非私有方法时相应类的名字应为其被定义的类而不是后者的子类(想不到吧)、输出类的关联关系时存在死循环。

第二次作业架构

第二次作业是三次作业中代码量最少的了,只需要新增6个方法就可以了,这里引入了描述动态模型的UML顺序图和时序图,新增的UMLElement包括生命线,消息,状态机,状态,状态迁移等。

第二次作业中我吸取了第一次作业的教训,对新增的元素都定义了相应的类,并将它们所需要进行的操作都内聚到了各自的类中,这样得到的代码也就相对简洁,在顶层类中定义的数据结构也就变的自然了。

OO第四单元总结

OO第四单元总结

上面给出了顶层类MyGeneralInteraciton中定义的数据结构以及MyInteraction类,其中在顶层类中不再出现官方库中的UMLElement,代替以自己定义的以My为前缀的类。而myInteraction就是其中的一个例子,它拥有自己的名称,id,父元素,下属生命线等,它同时也包含了计算本身生命线个数的方法,体现了面向对象编程思想的好处,也就是将逻辑上高度关联的数据集中在一起成为一个黑盒,并将向外提供简洁的接口,最后MyGeneralInteraction只需要调用简单的几个方法,就可以实现更复杂的需求。

第二次作业中出现的bug是由于在读取父类的时候,忽略了类的名字可能重复。这个错误导致获得了错误的父类并读取了其关联关系。还有就是没有虑到EndPoint也是状态机的一个状态导致了一个空指针的问题。

第三次作业架构

第三次作业引入了规范性检查,也就是要求输入的UML模型不能违背一些认为规定的准则,例如类不能有两个或者多个父类、继承关系不能成环、同一个类中的属性不能重名等等。

这些准则一共有八条,在我们编写的UML解析器类被实例化时就会进行检查,一旦查出错误,便直接退出,不再进行指令查询。这次作业的任务,就是完成这八个准则的检查方法。

本次作业无需额外定义新的类,只需要在原本的类中新增方法即可,在类图检查中,我们可以把类和接口看成是一个图中的点,而图中的边就是继承、实现关系,通过以不同的方法遍历图,就可以找到是否存在继承关系成环或者一个类多次实现某个接口的情况。同时为了加速这种遍历,还使用了并查集等算法。

第三次作业的bug,主要出现在遍历一个类实现的接口上错误计算了两个点之间连通路径的数量导致判断四号规则出错。

架构设计方法及其演进

第一单元

在第一个单元里,初步地接触了面向对象编程的思想,对多项式中的各个元素成分进行分类分层,逐步化解多项式求导本身的复杂性,也就是从底层的因子,到项再到多项式分别写一个类,并为它们写好加减乘求导等运算的接口,最后调用输入的多项式所实例化得到的对象的求导接口得到结果。

在这个单元的三次作业里,最开始只有一个单独的多项式类,随着后来多项式越来越复杂,引入了因子类,项类,但在最后代码依然复杂,各种调用层层叠叠,难以摸清脉络,究其原因是在设计之初中没有虑到后续功能可能的扩展,而在扩展时有不肯回头重构设计,因此产生了这种结果。然有经验不足的原因,但实在是一个失败的结果。

从第一单元中总结了许多经验,诸如类的高内聚,低耦合,类的模块化设计等等,还回顾了操作系统中的Unix设计哲学,最终将它们应用在了第二单元,省去了很多麻烦。

第二单元

第二单元是多线程编程,它和操作系统中的PV操作息息相关,在Java当中,通过锁机制和信号量等待来实现PV操作,因此多线程之间对资源的共享可以归结为对锁机制和信号量的适当使用。所以经过三次作业,对死锁的初步预防已经相当敏感,这是从这次作业中学会的一个地方。

这个单元的另一个重头戏就是合理的电梯调度策略,在这方面同学们做了许多分享和交流,最简单的一种想法就是调度器统一调度,另一种新奇的想法就是由各个电梯进行自由竞争,让各个电梯选择合适的人员进入电梯,两种方法各有优劣利弊,这里做一下简单分析:

统一调度的好处是可以做全局优化,综合各部电梯的位置方向剩余容量来做调度,调度算法相当自由,坏处是架构设计复杂,死锁预防难度大。

自由竞争的好处是各个电梯可以根据自己的种类做选择,调度简单,架构简单不易死锁,坏处是电梯之间互不知晓,可能效率有所降低。

电梯作业中预防死锁和调度策略两个难点相互影响,对设计者的验极大,我最后采取了相对保守的统一调度的策略,并修复了多次出现的死锁问题。

本次作业,面向对象的思想体现在调度器类和多个电梯的消息传递上。

第三单元

这一单元是JML语言建模,实质是让我们阅读并实现JML描述的类的接口,这一单元较为特殊,所需要的类已经基本定义好,只需选取特定的数据结构即可,本质上并无特别难的点,偶尔的阅读理解错误是bug的来源之一,另一个来源则是时间复杂度过高,例如在社交网络中查询两人的最短连接路径需要用到堆优化的迪杰斯特拉算法等。

第四单元

第四单元主要在于模仿UML建模语言,能够在Java中将其实现出来,类之间的继承、实现、关联关系是本单元的一个难点,可以把它们理解成为图的关系,也可以把它们理解成为映射的关系,不同的理解有着不同的实现,但关键还是在架构设计上,好的架构给实现以广阔的舞台,坏的架构让实现难有立足之地。

测试方法及演进

在oo作业中,我对测试一直不怎么上心(导致强测分数不高),思其原因,我想在与许多时候我对作业本身的要求并不理解同时较为懒惰,而要编写评测机,也就需要理解数据的产生机制,随机生成的数据往往测试起来效率低下,只有针对性的测试才能高效的进行测试。

在第一单元中,我采用了组合的方式来进行手动构造数据,即测试一个逐步复杂的函数列:

1,x,1*x,x^2,1*x^2,sin(X),1*sin(X),x*sin(X),1*x*sin(X)......

通过这种查找程序的bug,好处在于生成的逻辑简单,首先选取几个基本函数如1、x、sin(X)、cos(X)等,再将它们进行递归生成后续的结果进行测试。

在第二单元中,测试样例便在某个时间点、某个楼层的乘客请求,这时通过限制每个时间段产生的请求数量,通过随机生成楼层来进行测试。

第三单元则是将人员编号限定在一个特定的范围内,防止由于人员过于稀疏导致一直报错无法测试到相关的函数,通过让多人的程序对拍来查看正确性。

第四单元画了一些UML类图来进行测试。

课程收获

关于在oo课中的收获,其实前面几个单元的博客中,已经讲了很多了,这里并不想空发议论,如果非要有,那最后我想提的几点就是oo课程与别的课程都不太一样,它更多的是教会了我们去做,去设计,去测试,而不会让我们对着那些空泛的理论课程和繁复的语法大作文章,它不满足让我们了解几个Java巧妙的语法,而是让我们从零开始去设计。有一说一,我想许多人可能最开始是由怨气的,包括我,我做OO作业时经常是一个人一台电脑,从早上八点写到晚上十点,连续两天多一点把一周的作业写完,以至于写完OO后根本不想看OS的代码。我也经常跟舍友,跟6系的其他同学抱怨OO课的难度和劳累,但是,在多次从作业中体会和学习到OO的设计思想后,我认识到OO课是自己的事情,它并不是助教或者老师的事情,只有真正去设计了,去debug,去测试,去看看还有没有更好的架构,才能从这门课里学会东西,这种东西,绝不是从小到大我们接受的那种按部就班的课程所能带给我们的。感谢北航有这么一群人能够用心去打造这门课程,去让我们学会东西。尽管我的学习就好像一个行将溺死的人努力的去抓住一两根救命稻草,但是这样每学到一点东西,都让我倍感珍贵。

感谢所有为这门课付出的人,感谢老师,感谢助教。

课程建议

我在学习这门课程时,经常感慨这门课程之完善,助教和老师虑之周全。现在所能提的建议其实也只是一些细枝末节:

  1. 是否可以更加强调自主测试的重要性?
  2. 评论区是否可以进一步优化?这种百度贴吧式的交流对于学习来说似乎有所不足?
  3. 是否可以在每一单元结束之后公布优秀作业,供人观摩学习?

以上种种,用以告别本学期的OO课程,但学无止境,作为一门计算机专业的学生,我深知OO的学习还远未抵达终点。最后,再次向课程组表示感谢!

大佬总结

以上是大佬教程为你收集整理的OO第四单元总结全部内容,希望文章能够帮你解决OO第四单元总结所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。