zoukankan      html  css  js  c++  java
  • OO——第三单元JML规格编程总结

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

    JML存在的意义

    1. 开展规格化设计,能够实现设计与实现分离,实现进行提前测试。

    2. 方便程序代码的阅读和维护。

    JML方法规格

    requires —— pre-condition

    assignable —— side-effects,列出这个方法能够修改的类成员属性

    ensures —— post-condition

    区分正常功能行为和异常行为

    1 /*@ public normal_behavior
    2   @ 
    3   @ also
    4   @ public exceptional_behavior
    5   @ signals (Exception e) expr;
    6   @*/

    JML类型规格

    针对Java重定义的数据类型所设计的限制规则。

    invariant —— 不变式

    constraint —— 状态变化约束

    JML表达式

    esult

    old(expr) —— 这个使用起来需要注意

    forall

    exist

    othing

    ==>

    <==>

    等等,此处仅列举一些常用的

    JML应用工具链

    OpenJML —— 检测JML注释正确性

    JMLunitNG —— 进行测试

    等等

    二、部署JMLUnitNG/JMLUnit

     这个部分让AND gate同学彻底疯了,虽然自知时间有限+能力有限我怕是搞不了Graph,但是抱着尝试的态度,我还是自己写了一个简单的测试样例去做......

    但是,体验极差,虽然最后跑了一个什么东西出来,但是我甚至不知道是怎么跑出来的......

    接下来,我来记录一下我糟糕的体验过程...顺便希望得到一些指教。

    先放一下我自己的测试样例:

     1 package test;
     2 
     3 public class Test extends Exception{
     4     public static void main(String[] args) {
     5         try {
     6             divide(100, 20);
     7         } catch (Exception e) {}
     8     }
     9 
    10     /*@ public normal_behavior
    11       @ requires dividend != 0;
    12       @ ensures 
    esult == divisor / dividend;
    13       @ also
    14       @ public exceptional_behavior
    15       @ requires dividend == 0;
    16       @ signals (Exception e);
    17       @*/
    18     public static int divide(int divisor, int dividend) throws Exception {
    19         if (divisor == 0) {
    20             throw new Exception("hehe");
    21         } else {
    22             return divisor / dividend;
    23         }
    24     }
    25 }

    首先,我按照讨论区的方法开始使用——很好,前几步都很顺利,接下来就是噩梦的开始。

    我用javac编译文件,有一个.java文件无法编译,报错信息是一堆乱码:),然后我用idea打开看,idea的报错是,我的Test是个抽象类,无法被实例化......然后出现了Test.divide的地方也全都报错了。

    然后,我仔细地再看了一遍伦佬的教程,思考我和他的区别,我肤浅地觉得是我没有写package,然后我就写上了,然后就是彻底的噩梦的开始。

    本来只是一个文件没法用命令行编译,这回好了,我没有能编译的文件了???然后报错依然是一堆混杂着乱码的东西

    再后来,我琢磨着是不是包名的问题呢?但是我完全模仿伦佬,从文件名到包名到.java的名字和内容都一样,但是还是失败了——难道我是瞎哪边看错了写错了大小写???

    (由于急着交作业,我没有再从头尝试,之后我会再次尝试,看看能不能复现坑爹的结果)

    然后,我决定放弃用命令行来做这件事,我选择用ide。

    打开ide以后,我就慌了,因为在那个Test文件里,我出现了几处红色,但是我不会解决它,我抱着尝试的心态,点了run,然后居然——

    当然没有运行成功,但不是因为红色区域,而是,它提醒我jdk版本有问题?我???

    我又抱着尝试的心态,把jdk8换成了jdk11......居然,运行成功——在多处红色警告下,它运行出来了......

    我实在太震惊了,导致无话可说,我不知道我到底是怎么完成了这个任务的。我觉得这次尝试,除了震撼我妈以外,我没有什么收获。还请有人能赐教。

    三、架构设计梳理

    1/ 第一次作业

    这一次作业比较简单,基本按照所给规格写就完事了。

    唯一注意了一下的是当时怕时间复杂度太高,用hashmap做了一个双向的操作。即我用了两个hashmap,一个key值为id,value为path,另一个key值为path,value为id。

    这样在删除和通过path找id时都会更快一些。

    2/ 第二次作业

    单独开了一个floyd类来处理我的图,但其实并没有什么优越性......

    3/ 第三次作业

    我所有的图全都用二位数组实现了(没错是写死的),所有的边和节点全都用hashmap存储,后来上课知道这样设计非常垃圾......因为不能拓展,也很难修改。

    说起重构,其实也还是没有很好的想法,可能会建一个工厂来建不同的图吧......这样图就不会是写死的了......

    的确,这部分当时更关心算法和时间复杂度的问题,并没有去考虑架构的问题(当然其实也是有点不知道对于这次作业什么架构算是比较好的?)

    算法的话最后用的就是把换乘也算作权值,然后floyd到底。

    由于我觉得这个部分重在分析架构,但是我现在没什么特别好的想法,感觉算法没必要谈,大家心里都有数...所以就暂时简短地结束吧。

    以及我比较关心的一个问题是我知道可以用继承,让system继承graph,但是在graph的父类里我存了很多数据,我想在system里快速使用的话就想用protected关键字,但是这和checkstyle的检测冲突,这样我就要写一些新的方法,去完成一些事。第一,我不知道是不是我对继承理解有问题,父类的数据就是不能随便被子类使用的;第二,之前上C++课程的时候,老师却说尽量使用protected...是因为JAVA和C++特性不同吗?为什么此处我们不鼓励(起码checkstyle不鼓励)我们使用protected。

    四、BUG及修复情况

    很幸运......这单元三次作业强测和互测都没有出现什么问题,个人仅从想当然的角度思考自己的程序的话,先不论垃圾的架构,我更担心的是运行时间和内存,我甚至也不太担心运行时间,因为我觉得我的算法不会tle,但是的确会比较关心内存的使用,静态二维数组开的太多,我的每一条path都有自己的四个二维数组存一些数据,完整的图又有四个较大的二维数组......其实我没有很好地除了二维数组的建图方向,我觉得用邻接表...(特别是我知道有些同学用hashmap来模拟)会非常非常的慢。

    五、阐述对规格撰写和理解上的心得体会

    我觉得其实这次的实验训练,在规格撰写和阅读上并没有做的很多,更多的着眼点还是跟以前的作业给我的感觉差不多。

    其实JML的阅读体验还可以,除了有时候一堆(/forall,,)里嵌套(/forall,,)甚至还不止一层嵌套......但是这种情况不会太多,如果真的层数深了也说明这个方法设计并不是非常合理。

    第一次去实验的时候,写起规格还是挺懵逼的,懵逼的原因1、根本没有办法想清楚这个东西的定义,所以不会写;2、我自认为我脑内有了一个定义,但是我无法用JML的语言做出表达。但后来看了几次作业给我们的规格之后,写起来就比刚开始顺滑一些了。也能从JML的角度而不是实现的角度去看待一个方法了。

  • 相关阅读:
    村上春树的《海边的卡夫卡》与中日现实
    熊的甜蜜世界
    VS创建dll和调用dll
    DIRECTSHOW在VS2005中PVOID64问题和配置问题
    Vs 2008 解决方案的目录结构设置和管理
    SQL Server 2008中的代码安全(二):DDL触发器与登录触发器
    如何在自动SGA管理模式下调节参数设置
    将ORACLE数据库从归档改成非归档状态
    查看oracle数据库是否归档和修改归档模式(转)
    oracle TRANSLATE函数详解
  • 原文地址:https://www.cnblogs.com/senbei/p/10900857.html
Copyright © 2011-2022 走看看