规格化设计——OO第三单元总结

规格化设计——OO第三单元总结

一、JML语言理论基础、应用工具链

1.1 JML语言

? JML(java modeling language)是一种描述代码行为的语言,包括前置条件、副作用等等。JML是一种行为接口规格语言 (Behavior Interface Speci?cation Language,BISL),基于Larch方法构建。

? 通过使用JML,我们可以忽略一个类、一个方法内部的具体实现,专注于描述方法的预期功能,从而把过程性的思考延迟到方法设计中,扩展了面向对象设计的原则。

1.2 应用工具链

  • OpenJML:根据JML语言描述对模块的功能实现进行验证,逻辑证明其正确性。
  • JMLUnitNG:基于JML规格的自动化单元测试工具。

二、部署JMLUnitNG

public class Sub {
      /*@ public normal_behaviour
        @ requires a > 0 && b > 0;
        @ ensures \result == a - b;
        @*/
      public static int sub(int a, int b) {
          return a - b;
      }

    public static void main(String[] args) {
        sub(1, 1);
    }
}

在修改代码规格描述,使用OpenJML检验无误后可以生成和编译测试代码:

java -jar ../openjml/openjml.jar -check Sub.java > re.txt
java -jar jmlunitng-1_4.jar Sub.java
javac -cp jmlunitng-1_4.jar *.java
java -jar ../openjml/openjml.jar -rac Sub.java
java -cp jmlunitng-1_4.jar sub_JML_Test

之后即可测试代码,部分结果如下:

[TestNG] Running:
    Command line suite

Running:
Command line suite

Passed: racEnabled()
Passed: constructor sub()
Failed: static sub(-5464846548, -5464698148)
Passed: static sub(0, -9632483648)
Passed: static sub(2269875647, -2112489738)
Passed: static sub(-5963483648, 0)
Passed: static sub(0, 0)
Passed: static sub(5967483647, 0)
Passed: static sub(0, 2687483647)
Passed: static main(null)
Passed: static main({})

===============================================
Command line suite
Total tests run: 10, Failures: 1, Skips: 0
===============================================

三、作业架构分析

3.1 容器

? 第一次作业,只需要实现path和pathcontainer两个类。为了减少方法的时间复杂度,我选择了特定的数据结构,同时尽量把出现频率高的方法(查询)复杂度分担到出现较少的方法(增删)中:我实现了path的hashcode方法并使用了两个hashmap存储path和对应的id,保证查询path的复杂度接近o(n)。同时使用一个hashmap存储每个节点及其出现次数,计算node_count时直接返回size,复杂度小。Path中则采用ArrayList存储路径上的全部点。

3.2 扩展-图

? 第二次作业需要在PathContainer的基础上增加连通性判断、最短路径等图相关的方法,等同于要求扩展图的数据结构。
? 我使用了嵌套hashmap存储(节点-(相连的节点-连接次数))来记录图,每次增删路径时修改图。使用floyd算法求解两点最短路径:邻接矩阵original记录点之间的连接关系,每次增删时对应修改original并将新的original复制到二维矩阵routes,在routes中应用弗洛伊德算法可得到点与点之间的最短路径,最短路径不为MAX(代表点之间不连通)即是连通的,可求最短路径。
? 此外,为了将编号各异的点使用邻接矩阵管理起来,利用“同一时刻不超过250个点”这条数据限制,我将点的编号映射到0-249,代表在矩阵中的偏移。我使用了一个hashmap记录映射关系,使用了一个空闲点的堆栈来记录哪些点仍然可以提供映射。。

3.3 扩展-地铁换乘

? 由于低估了第三次作业的难度,这次作业的完成情况较为粗糙,设计和编码非常仓促:采用了同学之间普遍认同的算法计算最少换乘次数和最少票价;为了减少出错的可能,把上次作业中与图相关的部分全部封装到了一个类里。综上所述,并无多少自己深入的思考和独特的设计。

? 第三次作业的要求是扩展求联通块数量的功能和最小带权路径的功能(权值需要自己定义并计算)。

? 求联通块数量可以利用第二次作业中的图结构,采用单元点出发bfs搜索遍历所有到达点+依次将所有未标记节点作为起点的方式实现。

? 为了实现计算最少换乘、最小不满意度和最小票价,需要定义新的权。在设置好权值后,应用第二次作业的floyd算法即可,所以本次作业的关键是扩展新的数据结构存储权值。

? 求最少换乘时,应当把一条path上任意两点之间的边权值设为1;求最小票价时,应该把权值设置为两点之间的最短路径+2;求最小不满意度时则应该把权值设为最小不满意度+32。三种求解最后要相应地减去1, 2, 32以算出正确答案。归纳出三种方法的共性之后可以进行封装归类。

? 考虑到删除路径时对地铁结构影响较大,每次增删线路时,我都会重新扫描所有path建立新的邻接矩阵存储权值。

? 在扫描一条path计算权值时,我用到了spfa算法计算最短带权路径。

四、作业中的bug

? 第二次作业中修改邻接矩阵中自环的时机不对:自环应该在点被去除时消失,而不是在边被去除时消失。

? 第三次作业中,由于在上次作业中映射path中节点时没有判断该节点是否在图中存在,这个问题严重影响了第三次作业的评测:在强测中大量被包含“不存在于图中的节点”的样例攻击,出现大量nullpointer exception。归根结底,是在封装图的时候把规格和自认为冗余的代码删去了,导致出现了大量异常。(以惨痛的教训学习到规格和考虑重构后果的重要性)

五、单元心得体会

? 本单元的学习是一个较为完整的体会规格化设计和设计迭代的过程,虽说到了最后一次作业几乎已经无暇顾及阅读繁复的规格,但还是更深入地体会了继承的思想,学到了很多规格化设计的相关思想。

? 规格化设计一方面可以延迟过程性的思考,专注于描述算法的抽象实现和功能,从而方便了程序设计人员;另一方面,可以做到设计与实现分离,从而被广泛应用于对安全追求较高的大型软件开发中,在保证程序逻辑正确性的前提下分而治之,让不同的人根据规格编写不同的代码,并可以很方便地验证代码的正确性(JML工具链)。

原文地址:https://www.cnblogs.com/why34/p/10907680.html

时间: 2024-08-06 02:01:55

规格化设计——OO第三单元总结的相关文章

OO第三单元总结(规格设计)

OO第三单元总结 一.关于JML Java Modeling Language,即JML是一种规格化表示语言,主要用于对Java程序的各种方法功能的规范描述.这样做既可以给程序设计人员明确清晰的功能要求,又可以充分全面地验证已有的代码实现保证其满足规格描述的要求. 1.语法梳理 JML的语法清晰直观地描述了一个Java的各种特征.它的语法主要由以下三个部分组成. (1)表达式: 诸如 \result \old等有具体确定意义的固定关键词称为表达式.通过不同的搭配组合可以表示不同的含义,比如(\f

OO第三单元总结 JML

OO第三单元总结 JML JML语言的理论基础.应用工具链情况 JML是一种形式化的,面向JAVA的行为接口规格语言,它结合了Eiffel的契约方法和Larch方法,以及细化演算的一些元素,有着坚实的理论基础. JML最主要的语法有前置条件,后置条件,不变式,通过这些语法对输入和输出进行约束,也就是达成了一种契约.当模块实现后,只要输入输出满足这些约束表达式就满足了规格的要求.JML主要使用java的语法,除此之外还有自己的一些语法,比如/forall,/exist等等,来实现对输入输出的约束.

OO第三单元单元总结

目录 JML知识梳理 部署JMLUnitNG/JMLUnit 按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构 按照作业分析代码实现的bug和修复情况 阐述对规格撰写和理解上的心得体会 JML知识梳理 JML理论基础 关于JML的相关介绍其实课程给出的指导书就已经足够使用了,由于指导书上都有相关知识的梳理,所以这里不花费大量篇幅去书写这部分内容,只是简单提及一些东西.首先是什么是JML,课程进行,其实阅读简单的JML已经没有多大障碍了,但是对于JML的定义这种概念已经忘记的差不多了.JM

OO第三单元总结-规格化设计

OO规格化编程体验小结 1. JML语言的理论基础.应用工具链情况 JML 理论基础: JML建立契约式编程的基础上,是一种实现契约式编程的规格化语言.顾名思义,契约式编程,是供求双方建立在一定的契约上进行软件的开发和应用.类似于在共同完成这一个工程的时候我们对于每个方法都以一个供求双方都统一并且详细知晓的合同,在这个合同上,供应方要不多不少完成合同上的所有要求,需求方的可提出的需求范围只限于合同上的明确条文.这样同时明确了双方的权利和义务.而产生契约式编程的背景是很多工程的开发过程权责混乱,导

OO第三单元总结

JML语言理论基础 Java建模语言(Java Modeling Language,JML)是一种进行详细设计的符号语言,他鼓励你用一种全新的方式来看待Java的类和方法.JML是一种行为接口规格语言 (Behavior Interface Speci?cation Language,BISL),基于Larch方法构建.BISL提供了对方法和类型的规格定义手段.所谓接口即一个方法或类型外部可见的内容.通过在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却并不关心它的实现.使用

2019年北航OO第三单元(JML规格任务)总结

一.JML简介 1.1 JML与契约式设计 说起JML,就不得不提到契约式设计(Design by Contract).这种设计模式的始祖是1986年的Eiffel语言.它是一种限定了软件中每个元素所必需的责任与义务的开发模式,程序设计中的每个元素都需要用规范的语言精准地限定其前置条件(Preconditions).后置条件(Postconditions)和不变式(Invariants).通过这三项限定,我们可以清晰地获得对一个函数功能的刻画,从而达成设计与实现的分离,便于优化.测试和生成文档.

OO第三单元总结--根据JML写代码

一. JML语言 1. 理论基础 首先,JML不是JAVA的一部分,它是一群研究者为JAVA设计的扩展部分,但还没有得到官方的支持.因此,JAVA编译器并不支持JML,所以要想JML起作用,只能采用类似openJML这样的第三方来编译,将JML 规格编译为运行时检查的语句,即RAC code(runtime assertion checking).如果代码实现与其JML规格不一致,将引发运行时JML exception. JML遵从契约式设计范式(DBC),Design by contract是

OO第三单元总结——java建模语言

一.JML语言的理论基础 面向对象分析和设计的原则之一就是应当尽可能地把过程设想往后推.我们大多数人只在实现方法之前遵守这一规则.一旦确定了类及其接口并该开始实现方法时,我们就转向了过程设想. Java 建模语言(JML)将注释添加到 Java 代码中,这样我们就可以确定方法所执行的内容,而不必说明它们如何做到这一点.有了 JML,我们就可以描述方法预期的功能,无需考虑实现.通过这种方法,JML 将延迟过程设想的面向对象原则扩展到了方法设计阶段. 二.JML应用工具链 openJML可以检查规格

OO第三单元博客总结

原文地址:https://www.cnblogs.com/xiongmaoage/p/10903350.html