面向对象第三次课程总结

一、规格化设计的发展历史

  问了百度谷歌,都没什么标准的答案,这里就谈一下自己对于规格意义的理解吧。

  在实际工程中,一个完善、统一、严格的规格的确是很有意义的。尤其是在团队协作的项目里,一个统一的规格不仅能提高代码的可读性,同时,也方便使用者使用别人的编写的方法,在使用时只用关心其作用,而不必去考虑其具体实现

二、bug分析

规格bug

整体规范: this 应写为 \this

功能性bug

出现走“回头路”、“不存在的路”的现象

  原因:线程安全问题,当出租车进程执行pointbfs寻找最短(考虑流量)路径的同时,若流量刷新了,可能导致出租车无法找到流量最小的最短路径,可能会走一条固定的路径。

出现出租车停止的问题

  原因:当存在较多请求同时执行时,由于对出租车运行时sleep(500)的方法进行过修正,计算执行时间,直接调用sleep方法,当计算结果为负数时,程序抛出异常,该出租车进程直接结束了……

规格bug和功能性bug间的联系

  可以说对于道路流量的线程安全的考虑,都未在规格中体现出来,也就忽略了在执行pointbfs时可能会刷新流量,就导致了bug 的产生。

  而对于进程直接结束的问题,也可以说是对sleep方法的前置条件的忽略导致的bug。

三、规格不好的写法

未列举出应有的前置条件

    private static boolean isCrossroads(int index)
    // @REQUIRES: ;
    {
       int count = 0;

       for(int i=0;i<4;i++) {
           int next = index + Constant.moveOffect[i];
           if(next<0||next>6399) {
              continue;
           }

           if(guigv.m.graph[index][next]==1)
              count++;
       }

       if(count<=2)
           return false;
       return true;
    }

应改为

  private static boolean isCrossroads(int index)
    // @REQUIRES:  0 <= index < 6400;

前置条件不全

    private boolean canPickUp(Point _point, Point reqPoint)
    // @REQUIRES: _point != null && reqPoint != null;
    // @MODIFIES: ;
    // @EFFECTS: (req.canPickUp == true) ==> \result == true; else ==> \result == false;
    {
       if ((_point.x - reqPoint.x) > 2 || (reqPoint.x - _point.x) > 2)
    {
           return false;
       }
       if ((_point.y - reqPoint.y) > 2 || (reqPoint.y - _point.y) > 2)
    {
           return false;
       }
       return true;
    }

应改为

    private boolean canPickUp(Point _point, Point reqPoint)
    // @REQUIRES: _point != null && reqPoint != null && 0<= _point.x <80 && 0<= _point.y <80 && 0<= _ reqPoint.x <80 && 0<= _ reqPoint.y <80 ;

后置条件有误

    private boolean canPickUp(Point _point, Point reqPoint)
    // @REQUIRES: _point != null && reqPoint != null;
    // @MODIFIES: ;
    // @EFFECTS: (req.canPickUp == true) ==> \result == true; else ==> \result == false;
    {
       if ((_point.x - reqPoint.x) > 2 || (reqPoint.x - _point.x) > 2)
    {
           return false;
       }

       if ((_point.y - reqPoint.y) > 2 || (reqPoint.y - _point.y) > 2)
    {
           return false;
       }
       return true;
    }

应改为

    private boolean canPickUp(Point _point, Point reqPoint)
    // @EFFECTS: (\result == true) ==> (_point.x – 2 <= reqPoint.x <= _point.x + 2 && _point.y – 2 <= reqPoint.y <= _point.y + 2);

后置条件不必使用自然语言的地方使用了自然语言

    public int getStatus()
    // @EFFECTS: 获取出租车状态;
    {
       synchronized (this.statusLock) {
           return this.status;
       }
    }

应改为

  public int getStatus()
  // @EFFECTS: \result == \this.status;

后置条件使用自然语言

    private static void taxiInit()
    // @REQUIRES: ;
    // @MODIFIES:taxi.state;
    // @EFFECTS: Initialization of uninitialized taxi in file;
    {
       int x1, y1;
       for (int i = 0; i < Constant.taxiNum; i++) {
           if (Constant.taxi[i] == null) {
              x1 = (int) (Math.random() * 400) % 80;
              y1 = (int) (Math.random() * 400) % 80;
              if(i >= Constant.normalTaxi)
                  Constant.taxi[i] = new Taxi(i, x1, y1);
              else
                  Constant.taxi[i] = new TaxiVip(i, x1, y1);
           }
       }
    }

应改为

    private static void taxiInit()
    /** @EFFECTS: (\all int i; 0<=i<30; taxi[i] == new TaxiVip());
    * (\all int i; 0<=i<30; taxi[i] == new Taxi());
    */

前置条件后置条件都有问题

    public boolean equals(RequestData b)
    /**
     * @REQUIRES: None;
     * @MODIFIES: None;
     * @EFFECTS: (this == b)==> \result == true; (this != b) ==> \result == false;
     */
    {
       if (!this.pointFrom.equals(b.pointFrom))
return false;
if (!this.pointTo.equals(b.pointTo)) return false; if (!((this.reqTime / (100L)) == (b.reqTime / (100L)))) return false; return true; }

应改为

    public boolean equals(RequestData b)

    /**
     * @REQUIRES: b != null;
     * @MODIFIES: None;
     * @EFFECTS: (\result == true) ==> (\this.pointFrom == b.pointFrom && \this.pointTo == b.pointTo && \this.reqTime/ (100L) == b.reqTime/ (100L));
*(\result != true) ==> (\this.pointFrom != b.pointFrom || \this.pointTo != b.pointTo || \this.reqTime/ (100L) != b.reqTime/ (100L));
     */

四、心得体会

  这几次作业主要是对程序设计和规格的考察,但我还是在实现功能之后,再根据自己的程序来书写相应的规格。这几次作业,我都是在周三才基本实现功能,也就只剩下一点时间来写JSF了,所以程序中多见使用自然语言之处,也存在较多的漏写某些条件的情况。

  可以说,在我这几次的作业中,规格设计未起到积极作用,仅仅是为了少扣分而去写的。在这样的过程中,规格的作用根本没有体现出来。而在实际工程中,应当是先完善规格设计,再据此实现各个方法。

 

posted @ 2018-05-28 17:01  diralpo  阅读(156)  评论(0编辑  收藏  举报