OO第三次博客作业

OO第三次博客作业


规格化设计发展历史

二十世纪60年代以前,程序设计使用的主要是机器语言、汇编语言等,由于它们是针对特定型号计算机的语言,在不同计算机之间的可移植性差,而且不同计算机一般具有不同的指令系统,使得这类语言可读性极差。
二十世纪60年代中后期,软件的数量增多,规模增大,由于缺乏科学规范的系统规划与测试、评估标准,导致大批成本高昂的软件系统由于含有错误无法使用,甚至带来巨大损失。此时人们意识到程序的设计应易于保证正确性,也便于验证正确性,面向过程的程序设计方法开始出现。
80年代初开始,面向对象的程序设计开始出现。将任务抽象为对象以及对象的行为,面向具体的应用功能。对于每个封装的功能模块,只关心它的接口及能实现的功能,即方法的规格抽象。
进行规格抽象,有助于更直观的了解程序功能模块的输入限制、可以实现的功能等等。规格抽象中不关心具体的算法,降低了程序的阅读难度,提高了程序的易读性。从方法规格对模块进行检查,便于保证和验证程序的正确性。


规格bug

有幸没有被报规格bug,感谢测试的各位同学手下留情
自己在写程序的时候也是先写好了代码,再补全了规格,所以导致某些规格与代码不对应的情况存在。很多EFFECTS由于不能很好地抽象成规格,很多使用了自然语言代替,即使是抽象出来的,也写得不够全面、不规范。


前置和后置条件写法分析

前置:

  1. 闲逛状态选路方法
public Point getRandomWay(ArrayList<Point> p) {
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: return a random way that is available and has the lowest flow;
		 */

原以为在使用方法的时候限制了p!=null,就不需要在规格中说明了,改:

public Point getRandomWay(ArrayList<Point> p) {
		/**
		 * @REQUIRES: p!=null;
		 * @MODIFIES: None;
		 * @EFFECTS: (\exist int i;0<=i<p.size();the road between p.get(i) and the recent location of taxi has the lowest flow)==>\result == p.get(i);
		 */
  1. 获取最小流量方法
public int getLowest(ArrayList<Integer> a) {
		/**
		 * @REQUIRES: !a.isEmpty();
		 * @MODIFIES: None;
		 * @EFFECTS: /result == (\min a);
		 */

前置条件不完善,缺少a!=null的限制,改:

public int getLowest(ArrayList<Integer> a) {
		/**
		 * @REQUIRES: a!=null && !a.isEmpty();
		 * @MODIFIES: None;
		 * @EFFECTS: /result == (\min a);
		 */
  1. 消除请求红框方法
public void endRequest() {
		/**
		 * @REQUIRES: !guigv.srclist.isEmpty();
		 * @MODIFIES: guigv.srclist;
		 * EFFECTS: remove the red square of the finisied request; 
		 */

同上,改:

public void endRequest() {
		/**
		 * @REQUIRES: guigv.srclist != null && !guigv.srclist.isEmpty();
		 * @MODIFIES: guigv.srclist;
		 * EFFECTS: remove the red square of the finisied request; 
		 */
  1. 服务状态运行方法
public void movebfs(Point src, Point dst) {
		/**
		 * @REQUIRES: !src.equals(dst) && this.status != 2 && this.status!=3;
		 * @MODIFIES: this,guigv.flowmap;
		 * EFFECTS: move the taxi througe the route that was given by the bfs;
		 */

缺少对于src和dst范围的限制,改:

public void movebfs(Point src, Point dst) {
		/**
		 * @REQUIRES: 0<=src.x<80 && 0<=src.y<80 && !src.equals(dst) && this.status != 2 && this.status!=3;
		 * @MODIFIES: this,guigv.flowmap;
		 * EFFECTS: move the taxi througe the route that was given by the bfs;
		 */
  1. 判断两个方向是否是反向的方法
public boolean isOpposite(Direction d1, Direction d2) {
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: if the two directions are opposite, return true;else return false;
		 */

同1,没有限制在程序过程中限制的条件,改:

public boolean isOpposite(Direction d1, Direction d2) {
		/**
		 * @REQUIRES: d1!=null && d2!=null;
		 * @MODIFIES: None;
		 * @EFFECTS: if the two directions are opposite, return true;else return false;
		 */

后置:

  1. 闲逛状态选路方法
public Point getRandomWay(ArrayList<Point> p) {
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: return a random way that is available and has the lowest flow;
		 */

原EFFECTS为纯自然语言,改:

public Point getRandomWay(ArrayList<Point> p) {
		/**
		 * @REQUIRES: p!=null;
		 * @MODIFIES: None;
		 * @EFFECTS: (\exist int i;0<=i<p.size();the road between p.get(i) and the recent location of taxi has the lowest flow)==>\result == p.get(i);
		 */
  1. 判断两个方向是否为反向的方法
public boolean isOpposite(Direction d1, Direction d2) {
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: if the two directions are opposite, return true;else return false;
		 */

同上,EFFECTS完全使用自然语言,改:

public boolean isOpposite(Direction d1, Direction d2) {
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: (the two directions are opposite)==>\result == true;
		 *        (the two directions are not opposite)==>\result == false;
		 */
  1. 根据状态查找出租车的方法
public ArrayList<Integer> findTaxi(int status){
		/**
		 * @REQUIRES: 0 <= status <= 3;
		 * @MODIFIES: None;
		 * @EFFECTS: return a list that contains all taxis of which the taxistatus is status;
		 */

同上,改:

public ArrayList<Integer> findTaxi(int status){
		/**
		 * @REQUIRES: 0 <= status <= 3;
		 * @MODIFIES: None;
		 * @EFFECTS: (\exist ArrayList<Integer> a;a!=null;(\all guitaxi gt;guigv.taxilist.contains(gt);(gt.status == status)==>a.contains(gt)))==>\result == a;
		 */
  1. 获取出租车周围未关闭道路的方法
public ArrayList<Point> getAcessWay(){
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: return a list fo acessible ways around the taxi;
		 */

同上,改:

public ArrayList<Point> getAcessWay(){
		/**
		 * @REQUIRES: None;
		 * @MODIFIES: None;
		 * @EFFECTS: (\exist ArrayList<Point> a;a!=null;(\all Point p;a.contains(p);guigv.m.graph[this.x*80+this.y][p.x*80+p.y]==1))==>\result==a;
		 */
  1. 移动出租车的方法
public void move(Point p) {
		/**
		 * @REQUIRES: p!=null;
		 * @MODIFIES: this;
		 * @EFFECTS: set the properties of taxi;
		 */

同上,改:

public void move(Point p) {
		/**
		 * @REQUIRES: p!=null;
		 * @MODIFIES: this;
		 * @EFFECTS: this.x==p.x && this.y==p.y ;
		 * (guigv.m.graph[this.x*80+this.y][p.x*80+p.y]==1)==>(guigv.flowmap[this.x*80+this.y][p.x*80+p.y]==\old(guigv).flowmap[this.x*80+this.y][p.x*80+p.y] + 1);
		 */

功能bug和规格bug在方法上的聚集关系

由于作业中都是先写了代码,然后再补JSF,所以功能bug和规格bug之间没有必然的联系。
如果是按照规格写代码,则规格bug很有可能导致程序功能错误,出现功能bug的同时也很有可能规格中具有相关的bug


思路和体会

写作业的时候也没什么设计规格的思路,就是把代码逻辑翻译成了规格,现在想想倒是可以先把自己要写的方法的功能明确,根据功能和对输入的要求,设计规格。
这几次作业也没有按照正确的顺序来先写规格再写代码,只觉得这个东西有些麻烦,还没有体会到其中的好处吧。

posted @ 2018-05-29 19:58  lemeow  阅读(149)  评论(0编辑  收藏  举报