BUAA_OO_Unit3总结
面向对象第三单元的课程主要学习了Java Modeling Language(JML)语言的一些基本知识与使用,并在编程的过程中回顾java继承等特性,以及编程框架的合理安排等。下面从几个方面回顾梳理本单元内容。
JML语言基础
“JML语言是对Java程序进行规格化设计的一种表示语言”,主要用法一是开展规格化设计,二是针对已有代码书写其相应规格,以便维护。本单元的练习主要是针对第一个用法,当然用法二也有涉及。
本次学习JML语言还只是处于“Level 0”的水平,并且由于练习不足等原因,并没有较好地掌握,不能熟练写出标准的规格等,但是正确理解规格还是可以。还是谈回JML语言吧,对所学的一点JML语言知识列举一下,方便以后回顾。
注释结构
行注释 //@ annotation
块注释 /*@ annotation @*/
一般通过块注释定义方法规格,包括三个部分:前置条件(requires子句),副作用范围限定(assignable子句),后置条件(ensures子句)
JML表达式
仅列出常用表达式,回忆检查自己的理解。
\result表达式 :非void方法的返回结果。
\old(expr)表达式 :需要注意自己的目标是什么,尽量把目标括起来。
\type(type) 与 \typeof(expr) 表达式 :注意区分与使用,括号内的内容不同。
\forall表达式 与 \exists表达式 :某些方法规格需要结合使用。
方法规格与类型规格
我个人对方法规格和类型规格的理解仍然非常浅薄,方法规格针对某一方法确定了其前置条件、后置条件以及副作用限定;类型规格是针对Java程序中定义的数据类型设计的限制规则,主要包括不变式限制和约束限制。方法规格的书写不能违背类型规格的大条件约束,否则即使满足了方法规格的若干条件,也不能保证程序的正确性。
在学习中,这部分的难点我个人认为主要在于“规格的继承”,老师也用了较大的篇幅讲解这一部分。
作业设计架构
本单元三次作业是仿照面向对象工程设计为我们设置的题目,很遗憾的是我个人没有很好的理解作业架构的思想,把所有的功能实现相应的堆叠在Path和相应作业所需的容器中。关于check style,也只是简单提取单一方法,“硬生生“地尽量提高style的分数。如果功能有所扩展,必定很复杂。
(下图是第三次作业的架构图,根本谈不上架构)
代码bug及修复
第一次作业较为简单,套用java官方的一些容器还是可以很快完成这次作业功能要求的。这次作业中的bug是我在对node的hash()函数未能及时重写,导致无法完成equal() 的功能。
第二次作业在第一次的作业上扩展了graph的部分功能,我是采用了Floyd算法,求出了图在变动后的距离矩阵,从而可以直接返回两个结点的距离。这次作业的bug是由于架构设计不明确,在使用RemoveById()方法时,没有将更新矩阵的方法写入进去导致。所幸针对该情况的测试点只有一例(偷笑?)。
第三次作业我个人的主要问题是不能分析出解决问题的算法导致耽搁了很长时间,最终算法的实现也是参考讨论区同学们的想法,自己在这一块也是很欠缺思考。Bug主要有两点,一个是将单个path的距离矩阵如何正确的写入到总的距离矩阵中,其实现在也没有特别理解这一块的原理,把不同path中最小的距离赋给总的矩阵就行了,感觉不是很严谨,但又没有举出反例;另外一个是对空图的联接块定义问题,很傻的是我没有读懂该方法的JML(离散的坑这也要补)。
规格撰写及理解
自己对规格的撰写仅停留在老师课上的若干习题和上机实验中的题目,而且从自己的主观感受可能是正确的,但是仍不确定。但是在自己着手写的时候仍感觉有些吃力,特别是关于构造类型的方法规格,自己的写法也与老师的答案有些出入,欠缺一些思考。在上次课程中“大小容器“的部分很值得思考,从大到小,以及从小到大,都需要有所限制。
个人感觉JML的学习很有意义,在书写规格时,也相当于更加深层次的认识自己在做的工程。在较大型的工程中益处应该更能体现。