OO第三次博客作业

一、规格化设计发展历史及被重视的原因

  这个问题还真的不容易,我翻了很多网页!甚至还从百度知道里发现了往届学长的足迹,不过那个问题貌似到现在还没有有效的回答。由于相关的资料不多,所以我只能根据已有的资料来阐述一下规格化设计的历史和重要性吧。剧情不够,臆造来凑,hhh !任何事物都有一个发展的过程,不是在编程语言才诞生时,人们就重视规格化设计了。在此之前,应该有很多人都感受到了代码设计不规范而带来的坏处,突然有一天,一个人发现,哎?我这样规格化设计不就解决了问题了吗?然后啊,开始有了一种新的事物——规格化设计。所以我们OO课程也多了一个扣分项,JSF规范检查。以下是重点:在计算机诞生之初,软件的应用是很少的,后来,出现了软件危机,人们提出了软件工程的概念,再后来,面向对象思想被提出,规格化设计也逐渐走向成熟。:

  说到规格化设计的意义,还真的不一般。首先,用户不必为了使用过程而费神去看过程的主体,我们只需要关注如何用就行了。其次,方便代码的维护,这给我们的感受是非常真实贴切的,尤其在改需求时,如果你的代码设计没有做到规格化,那么经常牵一发而动全身,改了一处便会带来很多其他BUG。还有就是方便团队开发,如果团队里各自写各自的代码,不注意协调,那么带来的后果的不堪设想的,规格化设计就能避免这样的问题,从而提高团队开发的效率。

 

二、规格BUG分析

  这三次作业我总共被扣了两个JSF,加上一个未被发现的,共三个,如下表:

  第一个BUG是第一次接触JSF,根本搞不懂咋写,于是去GitHub上参考了一下学长的写 法,然而,学长的Effects在构造方法时都是类似于this.a=a; 于是我深以为然,于是就模仿着写,结果等到互测结束后,才知道要用 == 。另外两个BUG是因为modifies漏掉了一些内容,因为本来已经写好了JSF了,但是又因为debug改了一些内容,没有更新规格,就爆炸了。这三次JSF给我的感觉就是枯燥,在我看来,OO最大的乐趣就是享受如何设计自己的项目,将原来虚无缥缈的需求变成具体的可实现的东西。然而我们在第七次作业已经完成了绝大多数的内容,再到第九次作业时去写JSF,完全是为了应付作业而写的规格,举个非常不恰当的例子,就像把自己吃过的甘蔗再重新嚼一遍,嚼不好的话还要被扣分!二十多个类,几百个方法,未免给人不佳的体验。强烈建议下一届应该改变一下作业顺序,先写JSF,再开始出租车,否则JSF就根本达不到预期的训练效果。

 

三、五种优化写法

  不得不承认,我JSF写的的确不好,后置条件为了方便,几乎都是用自然语言写的,因此还有很大的改进空间,以下举几个栗子

  1.这是我新建一个TaxiArray的构造方法


TaxiArray(TaxiGUI taxiGUI) {
/**
* @REQUIRES: taxiGUI!=null
* @MODIFIES: \this.taxis;
* @EFFECTS:
* 新建100辆出租车
*/
for (int i=0;i<30;i++){
taxis[i]=new VIPTaxi();
taxis[i].id=i;
taxiGUI.SetTaxiType(i,1);
}
for (int i = 30; i < 100; i++) {
taxis[i] = new Taxi();
taxis[i].id = i;
taxiGUI.SetTaxiType(i,0);
}
}

  这个规范明显就不规范,我感觉更新为下面的会更好,

        /**
         * @REQUIRES: taxiGUI!=null
         * @MODIFIES: \this.taxis;
         * @EFFECTS:
         *          (\all int i; 0<=i<30; taxis[i] == new VIPTaxi();
         *          (\all int i; 0<=i<30; taxis[i] == new Taxi();
         *          update taxiGUI
         */

  2.这是我设置出租车状态的代码

 public synchronized void setToGetStop(int num) {
        /**
         * @REQUIRES: 0=<num<=99
         * @MODIFIES: \this.taxis;
         * @EFFECTS:
         *          设定指定的出租车状态为接单后停止
         * @THREAD_REQUIRES:
         * \locked(this);
         * @THREAD_EFFECTS:
         * \locked();
         */
        taxis[num].state = "toGetStop";
        taxis[num].taketime = 0;
        taxis[num].nowx = taxis[num].toX;
        taxis[num].nowy = taxis[num].toY;
    }

  改进后:

        /**
         * @REQUIRES: 0=<num<=99
         * @MODIFIES: \this.taxis;
         * @EFFECTS:
         *         \taxis[num].state == "toGetStop"; 
         *         \taxis[num].taketime == 0;
         *         \taxis[num].nowx == taxis[num].toX;
         *         \taxis[num].nowy == taxis[num].toY;
         * @THREAD_REQUIRES:
         * \locked(this);
         * @THREAD_EFFECTS:
         * \locked();
         */

   3.我的重写toString方法

 public String toString() {
        /**
         * @REQUIRES: None;
         * @MODIFIES: None;
         * @EFFECTS: 重写toString
         */
        return "from (" + from[0] + "," + from[1] + ") to (" + to[0] + "," + to[1] + ") time " + time;
    }

  改为:

         /**
         * @REQUIRES: None;
         * @MODIFIES: None;
         * @EFFECTS: \result == "from (" + from[0] + "," + from[1] + ") to (" + to[0] + "," + to[1] + ") time " + time;
         */

  4.我的将请求加入到请求队列中的方法

 private synchronized void addRequest(Request request) {
        /**
         @REQUIRES: request!=null
         @MODIFIES: \this.requests;
         @EFFECTS: 向requests中加入请求
         @THREAD_REQUIRES:
         \locked(this);
         @THREAD_EFFECTS:
         \locked();
         */
        requests.add(request);
    }

  改为:

         /**
         @REQUIRES: request!=null
         @MODIFIES: \this.requests;
         @EFFECTS:  (\requests.size == \old(\requests).size+1) && (\requests.contains(a)==true);
         @THREAD_REQUIRES:
         \locked(this);
         @THREAD_EFFECTS:
         \locked();
         */

  5.这是判断红绿灯地图中的一行是否符合Map规范的方法

 public boolean checkMap(String s) {
        /**
         @REQUIRES: s!=null;
         @MODIFIES: None;
         @EFFECTS: 判断s是否符合地图中每一行的规范
         */
        s = s.replaceAll("\\s*", ""); //去除字符串中所有空字符
        if (s.length() != 80) //判断一行是否有80个字符
            return false;
        for (int i = 0; i < 80; i++) {
            if (s.charAt(i) != '0' && s.charAt(i) != '1') { //判断是否由0,1组成
                return false;
            }
        }
        return true;
    }

  改为:

         /**
         @REQUIRES: s!=null;
         @MODIFIES: None;
         @EFFECTS: \result==(s.replaceAll("\\s*", "").length ==80) &&(all int i;0<=i<=80; s.charAt(i) == '0' || s.charAt(i) == '1'))
         */

 

四、功能BUG和规格BUG的聚集关系

作业次数 功能性BUG数目 规格BUG数目 功能性BUG分析 规格性BUG分析 功能和规格BUG间关系
第九次作业 0 0
第十次作业 1 2

LoadFile中地图没有出问题

是加红绿灯时改了一些代码

却没有复原

见上文 无关
第十一次作业 1 0 LoadFile中请求读入时间不对 无关

 

 

 

 

 

 

  由上面的表格来看,我的功能BUG和规格BUG之间的关系不太紧密,可能是因为代码都是在规格之前写的因素吧,这三次作业,平均每次只要加100-200行代码就行,因此,第七次作业的

代码已经免去了重新设计的步骤,所以规格只能在代码后写!

 

五、心得体会

  这三次作业和电梯比起来好多了,电梯是我永远的噩梦!通过这三次作业的洗礼,也就意味着OO代码作业结束啦!hhh,OO真的难,从开学到现在,我感觉我老了一年(QWQ),天天刷夜刷的。不过收获也是很多的,从写不到200行JAVA代码的小白到现在2000行的出租车,能力在不知不觉间就提升了,所有努力都是有回报的,突然想起一首老歌(也是童年的回忆):

每一次
都在徘徊孤单中坚强
每一次
就算很受伤也不闪泪光
我知道
我一直有双隐形的翅膀
带我飞 飞过绝望
不去想
他们拥有美丽的太阳
我看见
每天的夕阳也会有变化
我知道
我一直有双隐形的翅膀
带我飞 给我希望
我终于看到所有梦想都开花
追逐的年轻
歌声多嘹亮
我终于翱翔
用心凝望不害怕
哪里会有风就飞多远吧
不去想
他们拥有美丽的太阳
我看见
每天的夕阳也会有变化
我知道
我一直有双隐形的翅膀
带我飞 给我希望
我终于看到所有梦想都开花
追逐的年轻
歌声多嘹亮
我终于翱翔
用心凝望不害怕
哪里会有风就飞多远吧
隐形的翅膀让梦恒久比天长
留一个愿望让自己想象

 

posted on 2018-05-27 00:14  pangrong  阅读(176)  评论(1编辑  收藏  举报