zoukankan      html  css  js  c++  java
  • BUAAOO第三单元总结

    ---恢复内容开始---

    JML 语言

     理论基础

      JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。JML是一种行为接口规格语言Behavior Interface Specification LanguageBISL),基于Larch方法构建。它在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却并不关心它的实现。如果使用JML的话,我们就能够描述一个方法的预期的功能而不管他如何实现。通过这种方式,JML把过程性的思考延迟到方法设计中,从而扩展了面向对象设计的这个原则。
      那么添加这些标记语言有什么好处呢:

    • 能够更为精确地描述这些代码是做什么的
    • 能够高效地发现和修正程序中的bug
       
    • 可以在应用程序升级时降低引入bug的机会
       
    • 可以提早发现客户代码对类的错误使用
       
    • 可以提供与应用程序代码完全一致的JML格式的文档
       

     应用工具链

      OpenJML:OpenJML is a program verification tool for Java programs that allows you to check the specifications of programs annotated in the Java Modeling Language.

      JMLUnit:For each Java(TM) or JML source file, and for the top-level class or interface defined in that source file with the name of the source file, the commmand jmlunit, or the graphical user interface version jmlunit-gui , generates code for an abstract test oracle class, that can be used to test that class or interface with JUnit.

    JMLUnitNG/JMLUnit测试用例

    我使用了IDEA自带的插件进行简单的测试,简单流程如下

    选择Test

    一下是初始化和对size()的简单测试

    import com.oocourse.specs2.models.Graph;
    import com.oocourse.specs2.models.Path;
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    
    import static org.junit.Assert.*;
    
    public class MyGraphTest {
    
        @Before
        public void setUp() throws Exception {
            int[] p1 = {1, 2, 3};
            int[] p2 = {1, 2, 3, 6};
            int[] p3 = { 2, 3, 4, 5};
            Path path1 = new MyPath(p1);
            Path path2 = new MyPath(p2);
            Path path3 = new MyPath(p3);
            Graph graphA = new MyGraph();
            graphA.addPath(path1);
            graphA.addPath(path2);
            graphA.addPath(path3);
            System.out.println("begin");
        }
    
        @After
        public void tearDown() throws Exception {
            System.out.println("end");
        }
    
        @Test
        public void size() {
            Assert.assertEquals(1, graph.addPath(path1), 1);
        }

    最后完成测试

    程序架构

     第一次作业

    第一次作业是让我们完成MyPath和MyPathContainer的构建。对MyPath的架构三次作业没有任何变化,使用普通int数组完成nodelist的存储,同时增加一个Hashmap用于存储不同的node,使得containsNode函数和getDistinctNodeCount函数的复杂度降到O(1)。所有函数实现起来都不难。

    对MyPathContainer的实现,使用了三个Hashmap存储所有数据,分别是HashMap<Path, Integer> pmap,HashMap<Integer, Path> pidmap,HashMap<Integer, Integer> nodemap,三个map在add和remove时进行更新。pmap和pidmap使的查询是否有path和获取path的复杂度降低,而nodemap是用于统计所有不同的点的个数而使用。

     第二次作业

    第二次作业是让我们完成MyPath和MyGraph的构建。对于MyPath没有任何改动。

    对MyGraph,由于需要查询边,因此增加edgemap来用于查询。而对于查询两点是否连接的需求,我是用并查集操作,新增connectmap来对构建连接图,只要两个点的value相同就可以判断为连接。而对于getShortestPathLength函数,构建邻接表,使用广度优先遍历得到。以上几个map在每次add和remove的时候都会重新构建,且最短路径对每个点都会求出来,所以每次查询的复杂度都为O(1),但是在add和remove时候复杂度会非常高。

    具体实现见下图

      第三次作业

    第三次作业是让我们完成MyPath和MyRailwaySystem的构建。MyPath多了getUnpleasantValue函数,但并没有大改动。

    对MyRailwaySystem的构建,新增的getConnectedBlockCount函数直接在并查集的基础上统计有多少不同的value值就行了。而对于最少换乘,最低票价,最低不满意度,其实就是构建三个带不同权值的无向图,最少换乘图就是同一条Path的各个点都相连并设置权值为1,求出的结果减1。最低票价就是同一条Path各个点间算出需要的最低票价并加2就是权值,求出结果减2。最低不满意度就是同一条Path各个点间算出最低不满意度并加32就是权值,求出结果减32即可。这次我没有使用邻接表,而是构建了邻接矩阵,将各个点的id映射到邻接矩阵中,然后使用迪杰斯特拉算法求出最短路径,然后就得到了各个值。我也是在每次add和remove时就构建并算出全部的点对应的各项数据。

    这三次作业一二次是直接叠加,但是第三次由于前两次考虑欠妥,重构过多,使得结构异常臃肿。

    具体实现如下图

    BUG修复

    第一次作业的compareTo函数出现问题,因为我在比较的时候使用了两数相减和0比较,没有考虑溢出的情况,导致有较大的数据时就会产生错误的结果,因此我改成两数直接用if比大小就可以了。

    第二次作业由于我将equal直接使用==代替,在比较两个点是否连接时,由于我的map的value为Integer类型,我直接使用==,在数据量大时会判定两个值相等的value为不相等,从而造成isConnected函数出错,间接造成getShortestPathLength出错,这个错误也使得我强测只拿了60分。

    第三次作业我没有考虑当两个点相同时,价格和不满意度都返回0,我返回了错误的值导致错误。

    心得体会

    JML给我们带来的不仅仅只是一种规范化的语言,更是对整个架构的规范和思考,从怎么做到做什么,这是一种更高的层次。同时,利用JML和我们所写代码的结合,我们能进行更加高效和规范化的测试。然而我在这三次作业中做的还是太少,对JML的代码仅仅在于理解层次,用来方便写自己代码,对整个架构的理解还是太过于肤浅,这也导致了代码的复用性差,第三次重构的多,代码比较臃肿冗余,还有许多方面仍有欠缺。

    ---恢复内容结束---

  • 相关阅读:
    mvc UrlHelper
    Bootstrap框架
    Swiper插件
    JQuery 滚动条长度
    JQuery 全屏滚动
    JQuery TODOList
    JQuery 节点操作
    JQuery 事件委托 事件代理
    JQuery 关闭事件冒泡
    JQuery resize和scroll方法
  • 原文地址:https://www.cnblogs.com/Therp-GY/p/10902166.html
Copyright © 2011-2022 走看看