oo 第四单元UML&课程总结
Posted Tianyuan_2001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oo 第四单元UML&课程总结相关的知识,希望对你有一定的参考价值。
oo 第四单元UML&课程总结
一、 总结本单元作业的架构设计
本单元的作业是写一个UML图的解析器,而具体的将UML图解析成一个个的UmlElement元素的过程已经在官方包中给出,我们需要做的就是对UmlElement中的元素进行组织与数据结构的设计,以便获取图中的相关信息。
第一次作业
第一次作业仅仅涉及了Uml类图的解析,与我们平常写的Java代码有很大的相似性(当然刚开始的时候看不懂)。在一番时间的理解之后,对于Uml图内部的元素就有了基本的认识,然后就按照自己的理解来进行了数据结构的设计:
为了方便代码的重用,为所有的元素设置了一公共父类Node
,里边存放了一些基本的属性与最基础的一些功能例如获取id与name等等。之后所有带Node字样的类均继承此结点,下面介绍一下各个类中的一些基本的设计。
ClassNode
,这是用来表示类的结点。在其中存放了其具有的属性(Attribute)与方法(Operation),并存放了子结点(Class)与父节点(Class)以及其实现的接口(Interface)与其有关联的对端 (Class or Interface)。值得一提的是,对于属性与方法的存储方式均采取了二级索引的方式,即以name为一级索引,以id为二级索引,以HashMap<String, HashMap<String, AttributeNode>>
或是HashMap<String, HashMap<String, OperationNode>>
的形式存放,这样子能够将重名的方法与属性保存下来,便于之后查找重载的方法与重复的属性名称。OperationNode
,表示方法的结点,在其中利用HashMap<String, ParameterNode>
存放了方法中涉及到的变量。AttributeNode
,表示类属性的结点。ParameterNode
,表示变量的结点。InterfaceNode
,表示接口的结点,其中存放了其父结点(Interface)与子结点(Interface),同时存放了直接实现该节点的类(Class)以及关联的对端(Class or Interface)Initial
,进行初始化的类,利用Initial
中的方法可以将官方包中解析好的UmlElement
分发重组为自己设计的Node
,从而进行下一步工作。MainClass
,程序入口。MyUmlInteraction
,实现题目要求的种种方法。
考虑到查询的过程中出现了很多重复操作,且查询的过程中不再涉及到数据的添加,采用了缓存的思想来进行性能的优化,在第一次查询的时候按照正常计算的过程进行,同时将结果保存下来;在第二次以及之后的相同查询中,直接调用之前保存下来的结果,这样可以大大减少计算量,提高性能,缺点是浪费大量空间,但好像不卡空间。
下面是第一次作业的类图:
从类图中可以看出,整个架构还是比较明确的,所有的节点都通过ClassNode与MyUmlInteraction进行交互。
第二次作业
第二次作业在类图部分没有改动,新增了状态图与顺序图部分,但是新增部分的功能要求都较为简单,下面是对新增类的一些介绍:
-
StateMachineNode
,用来表示状态机的结点,其中存放了Region结点。 -
RegionNode
,是状态机的一个“区域”(自己起的名),状态机中状态以及状态转移等等都在Region的基础上完成,里边存储了各种状态(State)。 -
StateNode
,用来表示状态的结点,可以表示普通状态,初始状态,终止状态,维护一个flag变量来实现。 -
InteractionNode
,是用来表示顺序图的结点,其中存放了了生命线(Lifeline)。 -
LifelineNode
,是用来表示生命线的结点,其中存放了收发的消息(Message)。 -
MessageNode
,是用来表示消息的结点,其中存放了消息的发出者与接收者。
下面是第二次作业的类图:
从类图可以看出,在第一次作业的基础上新增了两个部分,从以ClassNode
为核心转变为了以ClassNode
,StateMachineNode
,InteractionNode
为核心的结构,最终由MyUmlGeneralInteraction
来进行调用。
第三次作业
第三次作业在第二次作业的基础上增加了有效性检查,为了功能实现的独立性,新增了一Check
类用以专门判断各种类型的错误,而检查的方法是最基础的遍历。值得一提的是debug时发现了自己的漏洞,在判断自关联两个end重名的情况时无法正确处理,根源是利用end的name作为key值维护了一个HashMap,改成了以id为索引的方式之后就能够成功运行了。
下面是第三次作业的类图:
可以看出是在第二次作业的基础上增加了Check
类,其余变化不大。
二、总结四个单元中架构的设计以及oo方法理解的演进
在oo四个单元的学习过程中,对于项目架构的设计以及面向对象方法的理解有了很大的提升,下面简单回顾一下:
- 第一单元表达式求导,由于之前C语言课程的影响,第一次接触Java的时候,写出来的代码其实还是面向过程的,里边的各个模块之间耦合性非常强,并没有做到功能的分离,这就导致了在三次任务之中重构了两次。因为对于oo理解的不深刻,当时并不明白“低耦合”这句话的意思,因此在设计出的类的方法之中加入了非常多的参数,这时候本质上其实就是面向过程的写法了。在具体设计的时候,按照层次(例如表达式-项-因子)进行了划分,但是由于每一个模块之间联系较强,这样的设计并没有很好的效果。
- 第二单元中的电梯,架构较之第一次有了非常大的提高,做到了每一个模块的功能分离,因此在每一次的迭代开发之中工作量大大减少,相比于第一次开发每个类的方法都是依赖于这个类的属性实现的,实现了很好的降耦,同时采用了分布式电梯的调度策略。但是由于是第一次接触多线程,对于线程安全的控制并没有做的非常好。
- 第三单元中,由于是按照JML给定的架构进行实现的,对于结构的设计并没有多大的参与。重点是对于性能的优化,采用了并查集的数据结构,同时采用了迪杰斯特拉算法的堆优化。
- 第四单元中的UML部分是设计的较为成功的一次,在每一个类的设计上都实现了良好的降耦,因此在第二三次的任务中,并不需要对原本的代码进行大的改动,仅仅需要添加新的属性与方法就能够实现功能的扩充。
三、总结在四个单元中测试理解与实践的演进
在四个单元之中的测试其实做的并不算成功,第一单元之中的测试在同学的帮助之下成功地搭建了评测机,做了充分的黑箱测试,也进行了部分极端的白箱测试;而在于之后的三个单元,由于自己不会搭建评测机,黑箱测试部分就很难进行下去,都采取了白箱测试的方式,但是白箱测试本身具有覆盖面并不广泛等缺点,因此对于项目的功能测试并不能做到十分的全面。经历了一个学期的学习之后,我愈发地认识到了测试对于项目的重要性,写好代码仅仅是第一步,之后一定要采取多种方式来进行测试,否则就很容易暴雷。
四、 总结自己的课程收获
在一个学期的学习之中还是收获良多的,最直接的是对于Java语言的应用以及对多线程内容的了解,更重要的是对于面向对象思想的初步接触与理解,对于UML图的相关知识有了一定的了解,能够看懂一些简单的JML规格,python水平也有了一定的增长(第一单元评测机),但同时由于经常通宵熬夜来完成oo作业,也增长了爆肝能力与心理承受能力。
五、立足于自己的体会给课程提三个具体改进建议
- 每一次作业的难度设置
第一二次作业的难度相较于第三四次大了不是一点半点,尤其是在刚刚接触oo这门课的时候,第一单元的作业非常容易劝退人,而第一单元的第一次作业与第二次作业之间的跨度还非常大(正则表达式不支持递归),本菜鸡在第一单元第二次作业的时候通宵达旦地更改代码,差点就放弃了,建议增加一些提示(比如递归下降)或者适当的调整一下作业的顺序
- 适当提前题目下放时间
每次题目的下放都是在本周的oo课结束之后才进行的,可能是想让同学们听课之后再去做题,但是在不知道题目的情况之下很可能出现听课没有重点的情况(参考隔壁OS实验课之前讲课),如果能够适当下放题目,提前知道自己需要学习什么知识,可能对于听课的侧重点就有了更明确的想法。
- 实验课给出评测结果(课下也行)
每一次实验课提交的代码都不知道结果如何,感觉就像对牛弹琴,如果是课上不给出评测结果可以理解,是让我们自己充分测试,但是课下依旧不给出评测结果实在是有些令人摸不着头脑。
以上是关于oo 第四单元UML&课程总结的主要内容,如果未能解决你的问题,请参考以下文章