OO第三次博客作业

JML理论基础及应用工具链


  1. 理论基础

    面向对象分析与设计的原则之一是程序化思维应尽可能地推迟。JML将这种思维扩展到方法设计阶段。参见这里 。JML 给我们提供了这样的工具,用来更明确地描述我们试图将一个方法实现什么功能,而不是去具体实现它。

    JML遵从契约式设计的软件设计模式。

契约式设计或者Design by Contract (DbC)是一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。

无论是设计阶段,还是验证阶段,这样的描述都可以发挥出巨大作用,原因在于它迫使我们在最开始设计时,就考虑清楚每个方法的职责。一方面,它让设计的事情归设计管,代码的事情归代码管,让设计和写代码分开,让这两者的思路更清晰,更纯粹;另一方面,清楚地划分出各个方法地职能,可以避免一些调用方和被调用方都做检查的冗余编码的情况出现,更重要的是在检查错误时更加容易。

事实上,自然语言也可以做相同的事情。不过JML的描述会更精确,这在自动化测试和形式验证等方面会很有优势。

 

  1. 应用工具链文档

    • jml-launcher (the launcher for the graphical user interface tools).

  • jml and jml-gui (the checker).

    • jmlc and jmlc-gui (compile for runtime assertion checking).

    • jmldoc and jmldoc-gui (a version of javadoc that includes JML specification information).

    • jmle (compile for executing or prototyping specifications).

    • jmlrac (a version of java, the VM, that includes the bin/jmlruntime.jar file in the CLASSPATH, for running files compiled with jmlc).

    • jmlre (a version of java, the VM, that includes the runtime support needed for executing specifications, for running files compiled with jmle).

    • jmlspec and jmlspec-gui (generate skeleton specification files from Java source files).

    • jmlunit and jmlunit-gui (produce unit testing code stubs for use with JUnit).

    • jtest (combines the work of jmlc and jmlunit)

    • jml-junit (a version of JUnit's swing user interface that includes the bin/jmlruntime.jar and bin/jmljunitruntime.jar files in the CLASSPATH, for running JML and JUnit based tests on files compiled with jmlc and test cases generated by jmlunit).

     

部署实验


java -jar jmlunitng.jar demo/Demo.java java -cp jmlunitng.jar demo/.java java -cp jmlunitng.jar demo/Demo_JML_Data/.java java -cp judge/openjml.jar -rac demo/Demo.java

 

 

在测demo时会发现,他多次生成的数据都是一样的,而且基本上都是int的边界数据。不明白NG在做数据生成的时候,是根据规格来生成的测试数据,还是根据输入的数据类型的边界值生成的测试数据?(如果NG每次生成的数据都是固定的,那这个工具的意义就没有那么大吧。。一定是我太low还没摸出来)还有一点问题是NG能否生成自定义对象。而不仅仅是Java原生的数据类型?可能还需要再摸一摸。

架构梳理


  1. 第一次作业

    基本没有可以自我发挥的余地。只有类 Path 和 PathContainer。谈不上有什么架构吧。只有一些局部优化像,Path作为一个不可变对象,hashcode只需要算一次。使用懒汉单例模式创建hashSet判断是否有Node。。

    关于架构唯一可以提到的就是:没有事先考虑到给代码留有可扩展的余地。每次迭代时都是复制上次代码而非extend和override。

  2. 第二次作业

    第一次意识到可以创建多个类来完成一个方法。但实现不是很好。架构有以下几个问题:

    • 图的构建和图的子结构混在一起,并没有分开建模。例如底层实现用了这样的形式 HashMap<Integer, HashMap<Integer, HashSet<Path>>> map; HashMap<Integer, HashMap<Integer, Integer>> map; 对此没有封装的意识其实是一种面向对象思维的缺失。这样的事无巨细的结构会显得很乱,无论是检查纠错,bug定位,代码复用对开发者而言都是很不友好的。

      真正好的结构应该能为开发者屏蔽掉一些复杂性,而不是带来更多的复杂性。 ——沃兹基

       

    • 图的构建和求最短路径的实现没有分开。事实上,图应该是较为静态的东西,而算法实现允许有一定程度变动来应对不同情景。这种策略机制分离,动态和静态分离的思路给代码带来更高的可复用性。

    • 没有事先考虑到给代码留有可扩展的余地。每次迭代时都是复制上次代码而非extend和override。

  3. 第三次作业

    架构是对第二次作业的将错就错,一错到底。

    - 依旧采取了这样的形式 `HashMap<Integer, HashMap<Integer, HashSet<Path>>> map;`  `HashMap<Integer, HashMap<Integer, Integer>> map;` 的底层设计。一点都不OO
    - 唯一值得一提的地方是,用到了接口实现了类似于函数指针的东西,从而实现了“三种最小”的统一建模。所有子类必须实现`calEdgeWeight(int nodeId1, int nodeId2);`和`calTransferWeight(int nodeId1, int nodeId2);` 两个方法。
    - 依旧存在第二次作业所存在的问题。直到看到标程才明白自己的上述问题。
  4. 重构?

    没有重构,架构是一路烂到底。只能靠对拍器苟活着。看完标程大概有一些感悟吧。一些随手记的日常:

    1,任务分层次很重要。一个任务往往不是由一个单独的类完成的。就像这次地铁的作业。图的构建可以拆开,底层的node,edge也可以封装起来。计算可以封装起来。 1.1,底层支撑性的结构 和 任务主要矛盾点应该分开。例如: 对于图构建,修改这一任务,node,edge就是底层支撑性的东西。可以让结构看起来很清晰。

    1.2,OS老师经常教导我们操作系统不要和硬件绑得太死。OO也是这样。对于计算点点最短路径这一任务,图就是底层支撑性的东西。不同实现的图,只要提供相同的接口。不同的最短路径算法也不需要和图结构绑定死。

    思考自己的代码,就是把所有的东西都装在脑子里,这样会有很乱的感觉。没有人可以同时把握住这么多的东西。真正优秀的面向对象应该要帮助人屏蔽掉一些复杂性,而不是带来更多的复杂性。

    2,一个方法能做的东西,可以封装一个类去做。 3,一个包能做的事情,可以把内些会变动的放在一个包里,把不会变动的放在另一个包里。例如,图的实现是相对静态的。而计算最短路径算法是可以变动的

 

bug修复


第一次作业中的 compareTo 在减法溢出上翻了车。后来学乖了,就写了对拍器。

 

心得体会


  1. 契约式的模式,给设计带来很多的好处。像最开始说的那样,无论是设计阶段,还是验证阶段,这样的规格描述都可以发挥出巨大作用,原因在于它迫使我们在最开始设计时,就考虑清楚每个方法的职责。一方面,它让设计的事情归设计管,代码的事情归代码管,让设计和写代码分开,让这两者的思路更清晰,更纯粹;另一方面,清楚地划分出各个方法地职能,可以避免一些调用方和被调用方都做检查的冗余编码的情况出现,更重要的是在检查错误时更加容易。

  2. 但其实也并不局限用JML来描述,如果我们的最终目的仅仅是形成清晰的设计架构,明确的责任划分而不是形式化验证。自然语言其实可以省去很多不必要的麻烦。

  3. Junit单元测试很有用,建立在拥有足够优秀数据集的前提下。JML静态推断,动态检查很高级,但需要大量的工作精力来维护JML注释。作为扩展学习,这两者是很棒的教程。

posted @ 2019-05-22 12:41  Cheney0114  阅读(155)  评论(0编辑  收藏  举报