• OO第三次博客作业


    规格化设计发展历史

    在调研的过程中再一次验证了“百度搜索不适合学术”这个观点,没有找到合适的搜索结果后,转用Google,才找到了一些细节。

    保证程序的正确性以及减少软件错误一直是程序员关注的问题,Hoare提出了基于“前置后置条件”的接口规格方法。

    为了建立正确的类规格,近些年来,研究者们进行了抽象变量、接口规格、状态抽象、查询方法等不同方面的尝试,并取得了很大的进展。

    为保证程序的正确性, Hoare[l] 提出了关于接口的规格方法,即若一种方法在执行前满足前置条件,运行后满足后置条件,那么这种方法就是正确的。 Hoare 提出的这个结论为规格化发展起到了奠基的作用,也为类中接口的规格化提供了理论基础。

    针对各方法的精确规格定义, MeyeP] 提出契约式编程延续了对方法的精确定义,但其不足是依赖内部状态来体现方法之间的相互依赖。

    课程中使用的JSF更偏向于“契约式设计”(Design by Contract):为传统的抽象数据结构增加了先验条件、后验条件和不变式。

    规格bug分析

    bug类型 bug内容 出现位置
    JSF检查->Requires不完整 忘写JSF Windows类
    方法规格检查->Effects不完整 JSF不完整 Taxi类
    方法规格检查->JSF不符合规范 可追踪出租车没有写继承 Taxi2类

    bug产生原因:

    • 第九次作业是JSF被扣分最严重的一次。我是写完代码然后再去写JSF,在金工实习上补全JSF就上交了,最后发现因为有一个类的JSF写漏了,对面对每一个没写的方法规格报了15个JSF imcomplete...
    • 不是太重视JSF,导致部分后置条件不够详细,最后两次作业总共被报了3个JSF。

    前置条件后置条件写法改进

    前置条件

    (1)修改前

    /** @REQUIRES : map!=null,taxiGUI!=null,GuiInfo!=null;
    	 * @MODIFIES : this.id,this.credit,this.map,this.taxiGUI,this.GuiInfo,this.flowMonitor,this.VIP;
    	 * @EFFECTS : None;
    	 */
    

    对新增变量flowMonitor判断
    修改后

    /** @REQUIRES : map!=null,taxiGUI!=null,GuiInfo!=null,flowMonitor!=null;
    	 * @MODIFIES : this.id,this.credit,this.map,this.taxiGUI,this.GuiInfo,this.flowMonitor,this.VIP;
    	 * @EFFECTS : None;
    	 */
    

    (2)修改前

    /** @REQUIRES : id > 0;
    	 * @MODIFIES : None;
    	 * @EFFECTS : 
    esult == id;
    	 */
    

    不需要对id进行判断
    修改后

    /** @REQUIRES : None;
    	 * @MODIFIES : None;
    	 * @EFFECTS : 
    esult == id;
    	 */
    

    (3)修改前

    /** @REQUIRES: None;
    	 * @MODIFIES: None;
    	 * @EFFECTS: 
    esult == System.currentTimeMills();
    	 */
    

    对于Thread进行追加Require
    修改后

    /** @REQUIRES: None;
    	 * @MODIFIES: None;
    	 * @EFFECTS: 
    esult == System.currentTimeMills();
    	 * @THREAD_REQUIRES:locked(	his);
    	 * @THREAD_EFFECTS:locked(	his);
    	 */
    

    (4)修改前

    /** @REQUIRES: None;
    	 * @MODIFIES: None;
    	 * @EFFECTS: (distance==1) ==> 
    esult = true
    	(distance!=1) ==> 
    esult = false
    	 */
    

    对于坐标范围的判断
    修改后

    /** @REQUIRES: src>0 && src <80 && dst >0 && dst < 80;
    	 * @MODIFIES: None;
    	 * @EFFECTS: (distance==1) ==> 
    esult = true
    	(distance!=1) ==> 
    esult = false
    	 */
    

    (5)修改前

    /** @REQUIRES : s!=null;
    	 * @MODIFIES : this.str;
    	 * @EFFECTS : str == s;
    	 */
    	public Request(String s) {
    

    基本数据类型不需要进行判断(编译器保证)
    修改后

    /** @REQUIRES : None;
    	 * @MODIFIES : this.str;
    	 * @EFFECTS : str == s;
    	 */
    	public Request(String s) {
    

    后置条件

    (1)修改前

    	/** @REQUIRES: requestQueue!=null;taxiGUI!=null;
    	 * @MODIFIES: this.requestQueue,this.taxiGUI;
    	 * @EFFECTS: None;
    	 */
    

    修改后

    	/** @REQUIRES: requestQueue!=null;taxiGUI!=null;
    	 * @MODIFIES: this.requestQueue,this.taxiGUI;
    	 * @EFFECTS: this.requestQueue == requestQueue, this.taxiGUI == taxiGUI;
    	 */
    

    (2)修改前

    /** @REQUIRES : None;
    	 * @MODIFIES : None;
    	 * @EFFECTS : 
    esult == invariant(this);
    	 */
    

    repOK 的具体判断
    修改后

    /** @REQUIRES : None;
    	 * @MODIFIES : None;
    	 * @EFFECTS : 
    esult = (requestQueue != null);
    	 */
    

    (3)修改前

    /**@REQUIRES : readFile!=null;taxiGUI!=null;flowMonitor!=null;GuiInfo!=null;
    	 * @MODIFIES : requestQueue,readFile,taxiGUI,flowMonitor,GuiInfo;
    	 * @EFFECTS : this.requestQueue == requestQueue;
    	 * 		this.readFile == readFile;
    	 * 		this.taxiGUI == taxiGUI;
    	 * 		this.flowMonitor == flowMonitor;
    	 */
    

    对新增的GuiInfo没有修改Effects
    修改后

    /**@REQUIRES : readFile!=null;taxiGUI!=null;flowMonitor!=null;GuiInfo!=null;
    	 * @MODIFIES : requestQueue,readFile,taxiGUI,flowMonitor,GuiInfo;
    	 * @EFFECTS : this.requestQueue == requestQueue;
    	 * 		this.readFile == readFile;
    	 * 		this.taxiGUI == taxiGUI;
    	 * 		this.flowMonitor == flowMonitor;
    	 * 		this.GuiInfo == GuiInfo;
    	 */
    

    (4)修改前

    /** @REQUIRES : str!=null;
    	 * @MODIFIES : this.reqSame,this.timeSame;
    	 * @EFFECTS : 
    equest.equals(同质请求添加到同质判断队列);
    	 */
    

    尽量转换自然语言为逻辑语句
    修改后

    /** @REQUIRES : str!=null;
    	 * @MODIFIES : this.reqSame,this.timeSame;
    	 * @EFFECTS : reqSame.add(str),timeSame.add(time)
    	 */
    

    (5)修改前

    /** @REQUIRES : taxis!=null;
    	 * @MODIFIES : None;
    	 * @EFFECTS :None;
    	 */
    

    get方法一定要写 esult !
    修改后

    /** @REQUIRES : taxis!=null;
    	 * @MODIFIES : None;
    	 * @EFFECTS : 
    esult == taxis;
    	 */
    

    功能bug和规格bug的聚集关系

    这次博客作业这样要求,按照可能的论证:由于不清楚代码的功能细节,所以导致出现了规格bug,这种规格bug伴随着方法的功能bug出现,所以会出现聚类关系。
    由于JSF是在代码收工之后写的,所以基本没有聚类关系。
    三次作业最严重的规格bug就是忘写部分JSF,其他出现规格bug的地方并没有出现功能问题。
    如果说有什么没有被报的功能bug,那么对应的规格bug一定是有的,只是没有被抓出来而已。

    设计与撰写规格的思路

    • Require部分:一般都是对于输入的形参做非空判断
    • Modify部分:对于方法写到的private变量挨个判断是否修改
    • Effects部分:对于Modify的变量变化的情况进行分析

    最后使用JSFTool.class进行复查

    心得体会

    最近几次OO作业感觉收获比较小,在做课程作业时对于Java的语法没有更深学习的动力,也没有Java与其他技术的结合应用,如果只是完成作业只需要JavaSE的部分语法基础而已。这两周花费大量时间在JSF的书写上,而且遇到对面的刁钻扣分也容易受到打击,可能大家都觉得相对于程序的功能Bug,要扣规格的分不要容易太多吧。

    参考文献
    [1]王伟,丁二玉,骆斌.基于抽象状态的类的行为规格化方法[J].计算机科学,2016,43(S1):457-460.

  • 相关阅读:
    PHP-redis命令之 列表(lists)
    PHP-redis命令之 散列(hashes)
    PHP-redis命令之 字符串 (strings)
    CentOS 7.0:搭建SVN服务器
    Redis 数据类型分析 字符串 哈希 列表 集合 有序集合 优缺点 分析 注意事项 存储结构
    CentOS 7安装配置Redis数据库
    封装微信分享到朋友/朋友圈js
    PHP 微信分享(及二次分享)
    Ajax登陆,使用Spring Security缓存跳转到登陆前的链接
    IDEA thymeleaf ${xxx.xxx}表达式报错,红色波浪线
  • 原文地址:https://www.cnblogs.com/Hooooober/p/9099292.html
Copyright © 2020-2023  润新知