BUAA_OO 第四单元UML编程总结

一、第四单元作业架构

这两次作业主要训练同学们结合starUML工具解析UML图的能力。两次作业都不算难,但是细节很繁琐。下面将逐一进行设计架构的分析。

1.1 第一次作业

第一次作业要求解析UML的类图,需要完成对类,类的属性,类的方法,类间继承,类实现接口等UnlElement的查询。本次作业涉及到了大量的UmlElement,看起来十分复杂,但经过分析我们不难看出这次的UmlElement可以层次化的分为三类:

1、最顶层类, 包含UmlClass,UmlInterface,UmlOperation等。这些元素表示UML图中具体的对象,并且里面包含着一些其他的UmlElement,同层次元素间存在着一些关关联。为了避免大量使用HashMap储存这些元素的信息,我按照OO思想直接给这些UmlElement单独建类,创建了MyClass类,MyOperation类(理论上UmlInterface也应该单独建类,但因为本次作业未涉及到关于UmlInterface太多,为了代码简化我还是没有添加MyInterface类)。从结果来看效果也十分良好,很多同学写完后需要殚精竭虑的思考如何将代码降到500行,而我代码一开始写完即使添加了大量单行注释MyUmlInteraction也才460行。

2、第二层元素包含UmlAttribute、UmlParameter等。这些元素本身是UmlClass等最顶层类的组成元素。只需将其添加进其所在顶层类即可。

3、第三层元素包含UmlInterfaceRealization、UmlGeneralization、UmlAssociation等。这些Element体现了最顶层类彼此之间的关系,类的继承关系我直接在MyClass类中通过parent_ID体现,剩下的关系则通过HashMap来储存。

总体而言,我的设计使用了OO思想,通过寻找类的层次化关系将Element彼此之间进行组合抽象成立新类,以进一步简化代码。

另外考虑到这次作业的输入并不是严格的顺序输入,可能存在乱序输入,即每个第二层元素出现时其所对应的最顶层元素还未出现,因此我进行了二次遍历,第一次遍历只统计最顶层类的信息,第二层统计第二层元素及第三层元素的信息。

 这次作业并不算很难,大部分函数直观简单,唯一有些难度的可能就是getImplementInterfaceList函数的实现了,这个需要考虑接口多继承和类本身单继承的问题。这个函数我通过单继承特性遍历类及其父类,寻找到所有其直接实现的Interface,然后使用与上次作业相似的bfs思路寻找到这些Interface继承的所有Interface并添加进来就好。

1.2 第二次作业

每次作业在写之前我都会先进行思考,预估大概的代码量,分析如何写才能简化代码实现过程,怎样写才能最直观的表现整体过程。经过思考,我本次作业最终选择构建四个类,分别为类图类,顺序图类,状态图类和单独的正确性检测方法类。四个类里每个类都建立一个图。

类图里基本将上次的代码直接复制过来就成,实现了类图相关的各个函数。

顺序图依据UML_LIFELINE、UML_INTERACTION、UML_MESSAGE这三个元素构建,实现了与顺序图相关的函数,如getMessageCount、getParticipantCount等。

状态图依据UML_STATE_MACHINE、UML_REGION、UML_FINAL_STATE、UML_PSEUDOSTATE、UML_STATE、UML_TRANSITION这六个元素构建,实现了与状态图相关的函数,如getStateCount、getSubsequentStateCount等。

正确性检测方法类基于类图检测有效性,因此这个类里面构建的图与类图构建方式一致。根据内部构造的类图实现了UML的三种有效性检测。

这次作业也是,虽然设计的概念繁琐而复杂,但搞明白之后实现过程却十分简单。与JML实现过程相似,本次作业使用了大量bfs方法以遍历得到相应的信息,在有第三单元作为铺垫的情况下,这次作业实现过程并不难。在我看来这次作业唯一稍有难度的就是正确性检测了,下面我将说明自己的正确性检测实现方法:

1、R001(针对下面给定的模型元素容器,不能含有重名的成员)实现思路很直率,只需统计出类本身的各个属性,然后通过hashMap找到其对应的所有associationEnd的名字,遍历看是否有名字重复出现即可。

2、R002(不能有循环继承)的实现过程我对于类和接口构建了不同的检测方法。对于类而言,因为类是单继承,我只需一直让其往上寻找父类,如果中间其自身再次出现则有问题需要添加。如果有非自身的元素出现两次或者到达顶级父类,则没问题,这个类无需添加。对于接口而言,接口涉及到多继承,因此遍历过程采用了bfs添加每一层的信息,并添加限制条件,看遍历完自身是否重复出现即可。

3、R003(任何一个类或接口不能重复继承另外一个接口)实现过程与类图中getImplementInterfaceList函数实现过程相似,对类进行遍历,看是否有接口重复出现即可。

二、四个单元架构设计与OO方法理解演进

2.1 第一单元多项式求导作业回顾

第一单元的内容是多项式求导。前两次作业中,我依据表达式的层次(加减乘除混搭的表达式、项、因子)把整个程序拆成类,这两次作业不是很难,只是让我初步拥有了对于OO思想的认识。

第三次作业复杂度高了一些,我的思路是用表达式树表示多项式,然后递归从下往上求导。在我看来第三次作业很好体现了面向对象思想,合理构造对象后可以利用继承与实现接口带来很大的便利。

 

2.2 第二单元电梯作业回顾

第二单元的主题是多线程。

三次作业的总体基于生产者-消费者这一模型来实现。前两次作业的两个线程分别是单部电梯线程、输入线程,共享对象是请求队列。第二次作业与第一次作业相比只是增加了增加了“调度策略”的问题,需要我们考虑如何安排调度,设计多线程锁,保证线程安全性。第三单元则直接增添了电梯数量,使得我们需要考虑更多多线程安全性的问题。在这个过程中,我不仅增加了对于多线程的理解,而且也对OO思想有了进一步的认识。每个电梯都是个类,调度器也是个类,每个类里面需要添加什么属性,设置哪些方法都需要我们进行缜密的思考设计。多线程涉及到多个类,十分复杂,但通过合理的抽象我们却可以极其方便地实现这种看起来异常困难的任务,这让我们不得不感慨抽象化及OO思想的威力。在这个过程中我进一步理解了OO思想,并认识到了OO设计的重要性。

这单元作业十分有趣,在我个人看来是四个单元里面最有意义,收获最大的一单元。

2.3 第三单元JML作业回顾

第三单元的主题是理解JML语言

第三单元的JML系列作业,向我们介绍了一种契约式的编程思想以及JML规格,并且基于这个思想逐步实现了对一个地铁线路图的分析。在这一单元作业中,课程组为我们提供了官方包,包含了每个接口或类需要实现的函数,即课程组已经为我们设计出了高质量的层次化结构。我们只需要根据源代码中的JML要求,实现官方包接口中的方法,并保证正确性即可。这次课程组为我们提供了现成的接口设计,我们只需实现即可。本次作业的最大难点在于算法部分如何拆点构图。通过完成作业我们可以增强自己的算法能力。在官方标准函数实现中,这几次作业布局相似,因此我们每次作业需要修改的部分并不是很多,修改一点即可完成新作业。通过思考分析课程组提供的优秀架构与方法实现,我认识到好的架构能让方法的具体实现更加游刃有余,避免了复杂凌乱的代码带来的灾难。最后在这单元作业中我大量使用了单元化测试工具,程序正确性检测水平也有所提升。

2.4 第四单元UML作业回顾

第四个单元的主题是UML图解析。

这个单元作业写下来之后看着自己的架构感觉非常良好。经过一学期的锻炼,我已经对于OO思想有了初步认识,遇到本单元作业第一反应就是寻找层次化关系以构造对象,最后写下来确实十分顺利。

 

三、测试理解与实践的演进

 在我看来OO课程不仅训练了我们面向过程的设计思想,也切实提升了我们的debug能力和程序完备性检测能力。

还记得第一单元刚开始的时候我还是使用人工方法,用纸尽可能完善的构造各种数据检测自己的求导程序,即使这样最后程序还是会出现bug,因为我自己提供的测试点还是会有所欠缺。

第二单元是多线程作业,没有固定答案,不好比对,数据也难以生成,因此我开始编写自己的评测脚本,用更先进的方法设计数据生成程序和正确性检测程序,体验了覆盖性测试的威力。

第三个单元的测试手段更加丰富。第三个单元的输出结果有确定的答案,因此可以沿用第二单元自动生成测试数据的方式,并直接使用对拍器验证正确性,无需构造输出数据正确性判断函数。此外除了整体测试,我们还可以利用JUNIT,TestMe等插件针对某个类实现单元测试,将测试的范围细化,使测试更具有针对性。

第四单元数据生成和检测都较为困难,因此此时我回归了最传统的做法,手动构造复杂数据并于同学交换数据测试。

在本学期OO课程中,通过互测和强测等环节我着实提升了自己的逻辑完备性及bug检测能力,收获颇丰。

四、课程收获

 一学期OO下来,不得不承认自己的代码能力有了巨大的提升。

首先,是代码能力的提升。大一的时候主要用C语言写一些算法程序,最多也就200行作业,因此听学长和老师介绍说OO一周需要写1000+行程序时还有些担心,不知道自己能否完成。而现在,1000-2000行的代码信手拈来,两天就能轻松搞定,着实进步了不少。

其次,是自己编程思想的改变。一学期下来,这门课程的训练让面向对象的思想深入我心。如今的我在写应用程序时第一反应就是寻找程序要求之间的抽象联系及层次,寻求创建合适的对象,可以说我的视野得到了很大的开阔。

然后,OO也锻炼我的测试能力。对于一个真正的程序员而言,工作绝不是写出程序就好,而是还要对程序进行检验,要保证程序的正确性。这与大一时写的程序也不一样,不是通过基本测试点就好了,而是需要花大量时间通过不同手段进行覆盖性测试确保自己的程序没有任何问题。本学期的作业就很符合这个思路,很多时候写完作业只需要1天左右,但测试却可能需要花2-3天的时间。

最后,OO也提升了我的阅读理解。OO的作业每次都以指导书的形式发放,包含许多细节方面的要求,形式上类似用户提出的需求,需要我花大量的时间阅读理解指导书才能正确设计程序。虽然以后用户的需求一定会远比OO作业复杂,但我相信经过OO课程的训练我已经有了初步的准备,以后能够较快地适应。

五、课程改进建议

1、这四个单元的内容都十分有意义,但是我个人还是感觉多线程单元最重要也最为复杂,其对应的训练量远远不够,颇有些浅尝即止。最后的JML单元和UML单元只是单纯的介绍两个新的工具(规格化语言和UML图),难点主要在于对概念的理解,算法和设计方面都不是很难。我认为这两单元完全可以通过实验课进行文字版考试的方法来锻炼,以更多地训练多线程,提升大家的编程能力。

2、实验课时间安排真的感觉不是很合理。每次都是上午讲完发放PPT下午就考,时间过于匆忙大家很那非常好地理解。希望以后可以修改实验课的时间,改为双周上实验。

3、这学期测试中显示的CPU时间与本地的CPU时间有较大差异。希望老师助教能够在平台上开放测试口,让同学们对于自己生成的数据进行提前检测,看运行时间,提前调整适应,以避免出现本地和最终测试的CPU时间差异过大的问题。

猜你喜欢

转载自www.cnblogs.com/super-dmz/p/11072013.html
今日推荐