OO第三次博客作业——规格

OO第三次博客作业——规格

一、调研结果:

规格的历史:

引自博文链接:http://blog.sina.com.cn/s/blog_473d5bba010001x9.html

传统科学的特点是发现世界,而软件的特点是构造世界。软件的最底层就是0,1,两个离散的值。

程序设计语言的三次分离使软件技术产生了飞跃

1950年代,第一次分离,主程序和子程序的分离程序结构模型是树状模型,子程序可先于主程序编写。通过使用库函数来简化编程,实现最初的代码重用。产生基本的软件开发过程:分析—设计—编码—测试,使大型软件系统的开发成为可能

1975—1980年代,第二次分离,规格说明(Spec)和体(body)的分离说明是类型定义和操作描述,体是操作的具体实现。(具体的例子就是C++,Java等面向对象语言的类说明与类实现的分离。)解决方案设计只关注说明,实现时引用或者设计体。体的更改、置换不影响规格说明,保证了可移植性。支持多机系统,但要同样环境。此时产生了划时代的面向对象技术。

1995—2000年代,第三次分离,对象使用和对象实现的分离

基于构件开发:标准化的软件构件如同硬件IC,可插拔,使用者只用外特性,不计内部实现。Web Services:软件就是服务。分布式,跨平台,松耦合。

为什么规格很重要?

这三次分离中的第二次就是OO课程要求我们去做的,也是面向对象的精髓。在大型项目的开发中,单个项目不可能由一个人完成。多人协作共同完成任务就意味着不仅仅需要知道自己的代码做了什么,还要知道别人的代码做了什么。自己的代码是自己写出来的,具体怎么实现,使用了什么样的数据结构,使用了什么样的算法,当然知道自己的程序会对什么产生影响,需要什么样的输入 。假设有个人写了一个方法,写好了,实现了,于是,他交了这份代码上去,你要使用这个方法,一看,这什么**玩意。花了时间适应了代码风格,知道要干嘛之后,写自己的代码进行测试,一测,bug,找了半天,发现是他和你的代码对于某个变量能不能修改有冲突。浪费了很长时间,再交给上面。。恶行循环。于是,规格的诞生可以说是拯救了这个局面。拿到代码,看前置条件,副作用,后置条件,就很清晰,永无bug(当然是不可能的)。

软件工程行业代码也越来越复杂,多人协作是必不可少,规格在我看来是代码风格的调和剂,多人项目运作的润滑油。

二、功能与规格BUG:

第9,10,11次,三次都没有被报功能bug和规格bug(当然不是我程序写得好,运气运气运气)。

但是还是想说明一下,自己在规格上的一些不足和功能上的一些不足。

JSF上:

JSFbug原因
后置条件使用了较多的自然语言因为部分方法在设计的时候没有设计好,行数较长,使用布尔表达式过于繁杂,有点嫌麻烦
副作用有几个函数存在问题,比如System.out缺失这是我刚和同学交流时才发现的(捂脸),刚开始的时候写了,但是JSF检查工具给我报wrong,我就一直没写emm

功能上:

功能bug原因
(前两次作业都存在,第11次作业修复)接客时正好处于请求起点时,车辆无法正常运行属于状态机中的边界状况,在计算下一个到达位置的时候,判断的是下一个位置与起始点,忽略了边界情况

三、列举不好的写法和改进:

前置1:不判断是否对象是否存在

 1 /**
 2      * @REQUIRES: None;
 3      * @MODIFIES: this.req; this.position;
 4      * @EFFECTS: this.req == req; this.position == position;
 5      */
 6     public Record(Request req, Point p) {
 7         this.req = req;
 8         this.position = p;
 9     }
10 //正确写法
11 /**
12      * @REQUIRES: req != null && p != null;
13      * @MODIFIES: this.req; this.position;
14      * @EFFECTS: this.req == req; this.position == position;
15      */
16     public Record(Request req, Point p) {
17         this.req = req;
18         this.position = p;
19     }

前置2:不判断值是否符合实际

/*** @REQUIRES: None;* @MODIFIES:this.index; * @EFFECTS: this.index == index;*/public TaxiCar(int index) {     this.index = index;}
//正确
/*** @REQUIRES: 0<=index<100;* @MODIFIES:this.index; * @EFFECTS: this.index == index;*/public TaxiCar(int index) {     this.index = index;}

前置3:未使用布尔表达式

/*** @REQUIRES: index is in 0-100;* @MODIFIES:this.index; * @EFFECTS: this.index == index;*/public TaxiCar(int index) {     this.index = index;}
//正确
/*** @REQUIRES: 0<=index<100;* @MODIFIES:this.index; * @EFFECTS: this.index == index;*/public TaxiCar(int index) { this.index = index;}

前置4:遗漏

/*** @REQUIRES: req != null;* @MODIFIES: this.req; this.position;* @EFFECTS: this.req == req; this.position == position;*/public Record(Request req, Point p) {this.req = req;this.position = p;}
//正确写法
/*** @REQUIRES: req != null && p != null;* @MODIFIES: this.req; this.position;* @EFFECTS: this.req == req; this.position == position;*/public Record(Request req, Point p) {this.req = req;this.position = p;}

前置5:布尔表达式描述逻辑错误

/*** @REQUIRES: req != null && index >= 80 || index < 0;* @MODIFIES: this.req; this.index;* @EFFECTS: this.req == req; this.index; */public Record(Request req, int index) {this.req = req;this.index = index;}
//正确写法
/*** @REQUIRES: req != null && (index >= 80 || index < 0);* @MODIFIES: this.req; this.index;* @EFFECTS: this.req == req; this.index; */public Record(Request req, int index) {this.req = req;this.index = index;}

后置1:未使用布尔表达式

/*** @REQUIRES: req != null && p != null;* @MODIFIES: this.req; this.position;* @EFFECTS: this.req = req; this.position = position;*/public Record(Request req, Point p) {this.req = req;this.position = p;}
//正确
/*** @REQUIRES: req != null && p != null;* @MODIFIES: this.req; this.position;* @EFFECTS: this.req == req; this.position == position;*/public Record(Request req, Point p) {this.req = req;this.position = p;}

后置2:使用自然语言

/*** @REQUIRES: req != null;* @MODIFIES: None;* @EFFECTS: 判断起始点与目标点是否为同一个点*/public boolean samedest(Request req) {if(req.getSrc().equals(req.getDst())) {return true;}else return false;}
//正确
/*** @REQUIRES: req != null;* @MODIFIES: None;* @EFFECTS: (req.getSrc() == req.getDst()) ==> \result == true;*           (req.getSrc() != req.getDst()) ==> \result == false;*/public boolean samedest(Request req) {if(req.getSrc().equals(req.getDst())) {return true;}else return false;}

后置3:未处理异常

public static int min (int[ ] a) throws NullPointerException, EmptyException 
/**@ EFFECTS:   \result == \min a;
*/
//正确
public static int min (int[ ] a) throws NullPointerException, EmptyException 
/**@ EFFECTS:   normal_behavior\result == \min a;
(a == null) ==> exceptional_behavior (NullPointerException);
(a.length == 0) ==> exceptional_behavior (EmptyException);
*/

后置4:描述不准确

/*** @REQUIRES : None; * @MODIFIES : this.AskList;* @EFFECTS : AskList.contains(ask);*/public synchronized void addAsk(Ask ask){AskList.add(ask);}
//修改为
/*** @REQUIRES : None; * @MODIFIES : this.AskList;* @EFFECTS : AskList.contains(ask) && AskList.size == \old(AskList).size + 1;*/public synchronized void addAsk(Ask ask){AskList.add(ask);}

后置5:多线程规格

/*** @REQUIRES : None; * @MODIFIES : this.AskList;* @EFFECTS : AskList.contains(ask) && AskList.size == \old(AskList).size + 1;*/public synchronized void addAsk(Ask ask){AskList.add(ask);}
//正确
/*** @REQUIRES : None; * @MODIFIES : this.AskList;* @EFFECTS : AskList.contains(ask) && AskList.size == \old(AskList).size + 1;* @THREAD_EFFECTS : \locked(Asklist);*/public synchronized void addAsk(Ask ask){AskList.add(ask);}

四、感想与体会:

首先说一下自己在写规格的体会。即便是知道规格的重要性,在第一次写规格的时候还是抗拒的,因为尤其是后置条件,全部写成布尔表达式是真的很难受。在OO实验课上提供的代码相对来说都比较简单,所以写成布尔表达式相对来说比较容易,使用布尔表达式来写具体实现也比较容易,但是自己写的代码有些结构相对来说比较复杂,除了一些比较简单的转换函数,JSF写的感觉很规范,其他都或多或少存在着问题。或者是实在想不到如何用布尔表达式表示偷摸摸用了自然语言啊,或者就像自己上面列的部分毛病啊,或者是自己对JSF原则上的一些忽略啊,等等。虽然这几次互测我没有被报bug,但是看周围同学被报的BUG,也知道自己的JSF存在很大的问题。

我在扣别人JSF时候,还是比较松的,第一次报了两个问题比较严重的,后面两次就只报了一个方法遗漏了JSF的bug。我会随机挑选几个函数的JSF进行查看,看能否get到这个函数的意思,我觉得能够让很多人快速理解代码的作用而不是每一行看代码找方法的作用就是JSF的精华。

还是挺开心的,OO的代码作业终于也是结束了,三次作业在设计上虽然不是十分的满意,但还是完成了基本的任务。虽然有一个边界条件直到最后一次作业才解决(其实我在第10次作业就发现了这个bug,原因是提交之前想测试一下能不能编译通过,结果出现了bug,复现了几遍都失败了,但是已经没有了时间,仅仅是初步判定了bug的可能位置,后来确实是我想的地方出了问题)。

最后,我记得第九次作业测试我的老哥在最后一个公测点,写了,和谐六系,OO不易,与君共勉,当时很感动。然后第10次和第11次作业都遇到了好人(或者是摸鱼测试者)。怎么说呢,虽然感谢老哥给我送分,但是感觉自己的程序的bug也被隐藏了emmmm。其实自己在课下有时候也能听到一些同学对OO互测的抱怨,有佛系测试者,有对结果很不满,有想击溃对面心理防线的(害怕&&鄙视),有恶意扣分获利的,怎么说呢,面向运气是一方面,课程的精髓有时候被掩盖了。引入公测是好事,虽然我是公测的受害者(为什么呢,因为第三次作业,格式上出了错误导致公测全WA,被判了无效,如果是后几次的测试模式,我觉得也就是一个BUG的事,不至于无效。也不是开脱,毕竟是自己不小心,甚至第四次作业临交前,对了十几遍输出害怕再无效。要说觉得很难受就是第四次作业的时候有同学甚至输出了调试信息,都没有判无效,觉得很不平emmmm)。

这句话真的很好,和谐六系,OO不易,与君共勉。一起走向未来,Code the world! Debug the world!

 

转载于:https://www.cnblogs.com/xiaoxin83121/p/9101785.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EndNote使用技巧之一--参考文献的导入

2012-11-20 11:54:15| 分类&#xff1a; 学术相关 | 标签&#xff1a; |字号大中小 订阅 一、怎样给课题组的其他人员共享我的library? 打开要共享的libirary→点击file→send to→compressed lirary→在 Send to Compressed Library 窗口确认储存路径与文件名&#xf…

5.29

查看linux系统中空闲内存/物理内存使用/剩余内存 free -m top命令 是Linux下常用的性能 分析工具 ps -eL |wc -l 查看进程数 ulimit -a 查看资源限制 echo DDS_ROOT 查看DDS设置的环境变量 tcpdump -i eth0 src 192.168.2.204 查看源IP204的eth0网卡的数据包接收情况 用vi进入…

primefaces_PrimeFaces在GlassFish 3.1.2.2上推动大气

primefacesPrimeFaces 3.4在三天前发布。 除了通常令人敬畏的新组件和更新组件外&#xff0c;它还包括新的PrimeFaces Push框架。 基于Atmosphere&#xff0c;这为您的应用程序提供了简单的推送机制。 这是在最新的GlassFish 3.1.2.2上配置和运行它的方法。 准备工作 像往常一…

相关的意义

第四章 相关系数 [内容导读]   本章的内容在课程中具有承上启下的重要作用。一方面&#xff0c;相关系数是反映与描述一组数据的概括性特征量数&#xff0c;只不过这里的数据是二元变量的观测数据。另一方面&#xff0c;对相关系数内容的理解与掌握&#xff0c;是建立在散点…

oo第三次作业

一、规格历史 最初的程序设计是直接面向机器的&#xff0c;代码编写困难、可读性差&#xff0c;当时对于软件开发的需求并不多。随着对于程序规模的需求&#xff0c;出现了面向过程的设计思想&#xff0c;开发者开始忽略底层实现&#xff0c;进行程序设计。对于面向过程设计思想…

帮助推动Java EE向前发展

如果您还记得我写的题为《 Java EE 8&#xff1a;当前状态是什么》的文章 &#xff0c;很明显&#xff0c;在过去的几个月中&#xff0c;Java EE的发展肯定已经放缓。 肯定有一些Java EE下的JSR具有比其他JSR更多的活动&#xff0c;但是自JavaOne 2015以来&#xff0c;整个Java…

35

1 转载于:https://www.cnblogs.com/venicid/p/9116284.html

glassfish默认密码_在MySQL上使用含盐密码的GlassFish JDBC安全性

glassfish默认密码我在该博客上最成功的文章之一是有关在GlassFish上使用基于表单的身份验证设置JDBC安全领域的文章 。 对这篇文章的一些评论使我意识到&#xff0c;要真正使它安全&#xff0c;应该做的还很多。 开箱即用的安全性 图片&#xff1a; TheKenChan &#xff08; …

Endnote生成的中英文混排参考文献中“等”与“et al”的处理

已有 12791 次阅读 2010-3-27 00:50 |个人分类:学习|系统分类:科研笔记|关键词:Endnote,参考文献,等,et al from: http://blog.sciencenet.cn/home.php?modspace&uid485&doblog&id306545 相信有很多科研工作者在管理参考文献、写论文时选用了Endnote作为首选参考…

【洛谷】P4643 【模板】动态dp

题解 在冬令营上听到冬眠的东西&#xff0c;现在都是板子了猫锟真的是好毒瘤啊(雾) (立个flag&#xff0c;我去thusc之前要把WC2018T1乱搞过去 &#xff09; 好的&#xff0c;我们可以参考猫锟的动态动态dp的课件&#xff0c;然后你发现你什么都看不懂&#xff08;菜啊 但是我们…

让 CentOS 启动时不启动桌面服务

[日期&#xff1a;2012-11-03] 来源&#xff1a;Linux社区 作者&#xff1a;kandyer [字体&#xff1a;大 中 小] 修改/etc/inittab文件&#xff0c;将 id:5:initdefault: 改为 id:3:initdefault: Linux 系统任何时候都运行在一个指定的运行级上&#xff0c;并且不同的运…

bzoj2721樱花——质因数分解

题目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id2721 可以知道 x 和 y 一定都大于 n! &#xff0c;不妨把 y 表示为 n!t &#xff1b; 那么 1/x 1/y 1/x 1/(n!t) 1/n! &#xff1b; 整理一下&#xff0c;最终变成&#xff1a;x (n!)/t 1 &#xff1b…

带有WildFly Swarm的远程JMS

我再次在博客上谈论WildFly群&#xff1f; 简短的版本是&#xff1a;我需要对远程JMS访问进行测试&#xff0c;并且拒绝设置复杂的功能&#xff08;如完整的应用程序服务器&#xff09;。 这个想法是要有一个简单的WildFly Swarm应用程序&#xff0c;该应用程序配置了队列和主题…

CentOS,重启的常用命令

重启命令 Linux中常用的关机和重新启动命令有shutdown、halt、reboot以及init&#xff0c;它们都可以达到关机和重新启动的目的&#xff0c;但是每个命令的内部工作过程是不同的&#xff0c;下面将逐一进行介绍。 1. shutdown shutdown命令用于安全关闭Linux系统。有些用户会…

nosql怎么使用_使用NoSQL实施实体服务–第5部分:使用云提高自治性

nosql怎么使用在之前的文章中&#xff0c;我讨论了如何通过结合使用Java Web Services &#xff0c; Java EE和CouchDB NoSQL数据库为产品构建SOA“实体”服务。 在本系列的最后一篇文章中&#xff0c;我将利用我已经创建的一些技术资产&#xff0c;并使用一些流行的SOA模式实现…

串口MSComm控件五种不同校验方式对数据收发的影响

(2008-09-10 14:50:00) http://blog.sina.com.cn/s/blog_470eccc60100arq7.html串口MSComm控件有五种校验方式&#xff0c;分别是无校验&#xff08;None&#xff09;&#xff0c;奇校验&#xff08;Odd&#xff09;&#xff0c;偶校验&#xff08;Even&#xff09;&#xff0c…

利刃 MVVMLight 3:双向数据绑定

利刃 MVVMLight 3&#xff1a;双向数据绑定 原文:利刃 MVVMLight 3&#xff1a;双向数据绑定上篇我们已经了解了MVVM的框架结构和运行原理。这里我们来看一下伟大的双向数据绑定。说到双向绑定&#xff0c;大家比较熟悉的应该就是AngularJS了&#xff0c;几乎所有的AngularJS 系…

使用Java扫描DynamoDB项目

在之前的文章中&#xff0c;我们介绍了如何查询DynamoDB数据库 查询DynamoDB第1部分 查询DynamoDB第2部分 。 除了发出查询之外&#xff0c;DynamoDB还提供扫描功能。 扫描所做的是获取您在DynamoDB表上可能拥有的所有项目。 因此&#xff0c;扫描不需要任何基于我们的分区键…

实战 SSH 端口转发

from: http://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/ 通过本文的介绍&#xff0c;读者可以从中了解到如何应用 SSH 端口转发机制来解决日常工作 / 生活中的一些问题。学会在非安全环境下使用端口转发来加密网络应用&#xff0c;保护个人隐私以及重要商业信息。…

627.Swap Salary-(LeetCode之Database篇)

问题描述 给出下面的表&#xff0c;名为salary。 idnamesexsalary1Am25002Bf15003Cm55004Df500要求执行一个UPDATE语句&#xff0c;将表转换成下面的样子。 idnamesexsalary1Af25002Bm15003Cf55004Dm500即m与f交换位置。 问题解决 下面我使用SQL中的case when来解决问题。…