UML 解析器设计分析 && OO 课程总结
一、设计分析
1. UML 类图解析器
-
这一单元的任务是深入学习 UML 的各种工具图,并用代码解析他们,在学习本单元前,我眼中的 UML 类图就是每次写单元总结时,用类和接口与他们之间的继承、实现等关系组成的连通图,但是在学习过本单元后,我了解到 starUML 对 UML 类图中的各个元素有着明确的规定,甚至在工程用都可以用 UML 图提前规划自己的工作。
-
第一次作业要求我们解析 UML 的类图,并执行一系列指令,因为这次的输入并不像上次的地铁系统可以随时输入,所以这次的作业就变成了存储与读取操作,我们只要选择良好可用的数据结构,就可以很好地完成这次作业。
-
我的读入方式是先把整个 UML 类图先按照结构等级排序,然后依次调用 Class、Operation、Attribute、Parameter、Association、Generalization 的读取函数,接口的读入也是同理,我几乎给每一个 UML 模型写了一个类,来完善我的操作空间。在存储上,因为会用到用名字查询相关的指令,我用了 id2Class 和 name2Class 两个数据结构存储 Class 的数据,这样在查询相关的指令中可以大大方便检测是否有异常以及查询结果。
-
下面是我的 UML 类图:
![]()
-
可以看出我几乎是给每一个有下级结构的 UML 对象写了一个类,保证了我可以直接调用上级对象得到下级对象的相关信息。
2. UML 类图、顺序图、状态图解析器以及规则验证
- 第二次 UML 作业,也是最后一次 OO 的代码作业了,与第一次作业比起来,这次加入了顺序图与状态图的解析,初看这两种不同的模型可能会很懵,但是仔细分析 starUML 中的结构可以发现这两种模型图也不过是几个对象之间的交互,和类图并没有太大的区别,一样也只是存储与读取的操作。
- 所以这次的难点主要在三个规则验证中,分别要检验是否重名、是否有循环继承、是否重复继承或实现接口;
- 验证循环继承中,我将整个类图或接口图化作一个有向图,然后运用强连通分量的算法找出成组的强连通分量,如果其个数大于 1 或者有自身成环就判定它有循环继承;
- 验证是否重复继承接口我将类的实现接口和接口的继承是为添加有向图中的一条边,然后在检查时运行深度搜索算法,找到某个类或接口所继承的全部接口,如果有重复的就判断它不符合规则。
- 验证重名是这里面最简单的一个了,只需要在存储是加一个条件就好了。
- 下面是我第二次作业的 UML 类图:
![]()
二、Bug 分析
- 这次没有互测所以我就说说我自己程序中的 Bug 吧:
- UML 类图表明了所生成的类图必须要能在 Java 8 中实现,所以类不能有多个父类,但是我却忘记考虑了接口可以有多个父接口,导致了一旦有多个父接口会将接口原来的父亲给覆盖掉,导致了在出现接口多父类的情况下会报错。
- UML 的顺序图中每次遇到 UMLMessage 时我都会获取这个 message 的 target ,以便存入相应的 lifeline ,可以我没有考虑到 message 的目标可以不是 lifeline ,还可以是 EndPoint ,这就导致了在这种情况下我获取 target 或造成 NullPointer 的错误,实属不应该,我最好在读取时判断一下对象是否有效。
- 这两处 bug 直接导致了我在两次作业中都没有拿到满分,真实可惜了,在 OO 的最后一单元作业中没有拿到一个完美的结局。
三、本单元的收获与总结
- 通过这个单元的学习,我了解到 UML 模型图的强大之处,他可以在不完善代码的情况下,现将整个工程的框架构建出来,再结合上 JML 的规定,这两者可以很好地完成对整个工程的限制及运作的规定,在部署任务及作业上有极大的便利之处。
- 同时 UML 模型也对于自己了解自己程序的价格很有帮助,可以从图中一眼看出类之间的继承等关系,帮助自己改进代码。
- 虽说这单元的作业是考验我们解析 UML 模型图的能力,但是我对于面向对象编程的能力在本单元达到了一个极致,我把每一个可操作的 UML 对象都写成了一个类,并对其新建对象进行操作,有点面向对象编程理念中的“万物皆是对象”的感觉。
四、对 OO 课程的总结
- 一学期的 OO 课结束了,我也经历了多项式求导、电梯调度、JML 规格、UML 模型图的洗礼,对面向对象的思想也越加敬佩,不免膜拜一下 Java 这门语言的设计者,这么精巧的一个个类,实现了我们对代码的精准控制;
- 下面是我在四个单元中的主要收获:
- 多项式求导:
- 对正则表达式有了非常熟练的运用,同时完成了自己写的第一个 Java 中的递归函数,对 OO 的思想有了大致的了解,学会了把每种不同的对象分为不同的类进行操作,这也是我对“面向对象”这个术语的初步认识;
- 这一单元,我主要的测试方法是构造特殊数据,边界条件数据来测试自己的或者他人的程序。
- 电梯调度:
- 在自己完成三个多线程的程序编写后,对 Thread 这个类可谓是运用自如,在多线程的调度上我也花了很多心思用于设计算法上;
- 运用面向对象的思想,将每个线程分为不同的类,可以方便地管理多线程的同步及互斥问题;
- 本单元我们几位同学编写了测评机,用随机生成的楼层请求来跑我们的代码,以及在互测中找到别人的 bug ,有了这个评测机,我们就可以大胆地优化时间,不必担心无法发现正确性的问题。
- JML 规格:
- 在这里我学习到 JML 是一种用于调用者和函数之间制定一个承诺,调用者只需要告诉我们输入输出的规则,我们就可以对这部分方法进行具体的代码实现,同时这部分的作业考验了我对数据结构知识的熟练程度;
- 这单元的代码编写让我对面向对象的思想进一步认识,特别是最后一次地铁系统,我把每一种计算方式单独建一个类,在其内部完成交互与运算,既可以保证模块的独立性,又可以使程序符合 checkstyle ,可谓一举两得。
- 这一单元我也用的是我们自编自写的测评机,自动生成点与边的数据,完成了自查 bug 与互测。
- UML 模型图:
- 这一单元我理解了 UML 的构成原理,通过自己手动画了很多类图进行测试样例的构造也较为深入的理解了三种不同的模型图。在上文也提及,这里就不再赘述了。
- Bug 的测试方法依然是我们自己的评测机,我觉得比较多要注意的是取出来的元素要判断一下是不是 null ,可能 Java 对空指针的控制不太友好吧。
- 多项式求导:
- 这门课中,我们几位同学经常在课下完成自己的评测机,这不仅训练了我们手写 Java 代码的能力,也让我们从出题者的角度去思考应该怎么构造测试样例,应该怎么怎么完成批处理以及验证正确性,这样锻炼了我们的团队协作能力和 python、shell 代码的能力,加深了我对测试的理解;
- 另外,在 JML 单元我也自己编写了一份 JUnit 用于对每个模块单独测试其正确性,让我认识到 JML 原来不仅仅是一份注释,更是一门可读的语言,在测试项目时起了很大作用。
五、对 OO 课程的建议
- 通过对 OO 这门课一学期的学习,我对它的态度也从最开始的大家的贬褒不一到现在很感谢这门课,它通过一周周的作业让我领略到面向对象编程的乐趣,但是我觉得这门课也有一些能改进的地方,希望可以给下一届的学弟学妹带来一些更好地体验:
- 指导书确实有一些地方说明的不清楚,比如最后一单元有很多内容都是后期暖心帖或助教在讨论区说明的,这就导致了前期我们不太敢写代码,怕需求会变;
- 在每次作业中可以在网页上给出一个标程的输出接口,我们可以把有争议的数据输入到网页上这个地方,通过得出的结果来判断争议的结果是什么,这样既可以有效地解决争议,又可以保证我们无法从这个标程接口获取任何和标程代码相关的信息;
- 希望今后的作业尽量不要拖到考期,或许可以通过减少作业次数的方式,让下一届的学弟学妹在考期前就把 OO 这门课的任务完成,像上学期的计算机组成原理,就是在考期停止考试,让同学们专心复习。
- 实验课尽量不要下午考上午才讲过的内容,我们还没有完全理解就测验似乎是不太合理的。
- 总之,OO 这门课相较于去年是有很大改进的,也希望“面向对象及其课程设计”能在今后的日子里越办越好!



浙公网安备 33010602011771号