OO第三次博客

一、规格化设计相关

  编程语言的规格化使用历史在网上的资料真的很少,我查阅了维基百科和谷歌学术的相关论文,关于这部分的讨论非常少。但可以确定的是,规格化的使用和工业上规范规格是有很大关系的,程序语言的发展和工业制造的发展有着一定的相似性。诸如国际化标准组织ISO,其宗旨是促进时间范围内的标准化工作的发展,推动国际间知识、科学、技术和经济方面的合作。具体来讲,它需要协调世界范围内的标准化工作,与其他国际性组织合作研究有关标准化问题。我们课上所讲和课下所用的规格化是为了规范方法使用的。工业产品和程序一样是面向用户生产的,这个用户可以是通常意义上的普通消费者,也可以是企业用户。在面向企业用户的制造中,工业产品的规格化可以申明产品的属性,包括各种尺寸,用途等;程序的规格化可以说明程序的用途、使用方法、使用条件和副作用。一段代码非常重要的一个用途,是让别人看懂,其次才是可以运行。

  正因如此,程序规格化设计越来越被人们重视,其对于代码编写的规范能够让程序变得更加易懂,能让使用者更加轻松简单的学会如何正确使用这段程序。此外,通过规格的抽象和总结,使用者能够直接使用这段程序而免去浪费大量时间来看懂代码的痛苦过程。更重要的是,代码的维护变得更加简单。其一,按我自身的经历,程序中隐藏的逻辑错误比如括号位置写错或者其他有关优先级的bug,在找到相应错误方法后能够非常轻松的通过抽象出来的规格判断代码具体错误位置。其二,在真正的做项目开发时,规格化设计能够方便整个团队的开发,因其能够统一规范每个人的编写方式,能使分工更加细致,使团队之间更加协调。


二、规格bug

  分析:首先标签格式错误这个问题只在第一次使用规格书写,也就是第九次作业时有。由于经验不足,我把REQUIRES、MODIFIES和EFFECTS全写成了小写。THREAD_EFFECTS和THREAD_REQUIRES错误同样也是在第九次作业中产生的,对于需要同步的方法和对象我并没有书写完全。EFFECTS不是布尔表达式这个bug被报了不少次,最基本的也是在第九次作业中,某些方法的规格书写不是非常完善,导致了后续作业继承过去的代码同样有规格上不完善的地方,而且由于一些不谨慎的原因,后续作业新编写的方法同样有一些不规范的地方,比如前置条件不完等。


三、改进

1.

/**
 * @REQUIRES: None
 * @MODIFIES: None
 * @EFFECTS: (\all int i; 0<=i<=r.taxis.size())==>\result.contains(MAX(r.taxis.get(i).credit))
 */

  在这个方法中,输入参数为一个具体的Request对象,方法功能是找到抢到该订单的拥有最大信用的出租车并返回,具体返回值是一个包含信用最大出租车的ArrayList。在方法具体的实现上,我并没有考虑输入指向空的情况,因此这部分JSF的前置条件写的不完整。此外,关于这个函数的后置条件我想了很久,找到最大值的部分如果使用方法内的具体代码会使后置条件变成算法实现,所以在这部分中使用一定的自然语言是相对合理的。

  改进如下

/**
 * @REQUIRES: r!=null
 * @MODIFIES: None
 * @EFFECTS: (\all int i; 0<=i<r.taxis.size) && (\exists int j; 0<=j<r.taxis.size && r.taxis[j].credit>=r.taxis[i]) * ==>\result.contains(j)==true
 */

2.

/**
 * @REQUIRES: None
 * @MODIFIES: position of this taxi this.x, this.y, this.roadchanged, this.time
 * @EFFECTS: (\ exists points connected and nearest)==>taxi.position = point
 */

  这一部分代码是出租车核心组成部分之一。其具体工作内容是在出租车处于去订单起始地点接乘客和接到乘客之后送乘客去订单目的地。上述规格书写中前置条件写的并不完整,副作用不清晰。这个方法具体上只管出租车的具体行进,其中寻路部分是使用其他方法直接计算返回一个相邻的最佳的点。参数输入部分只有一个Point类型的p,内容为出租车现在所处的点。把他设计成参数输入是为了避免其他可能的对出租车位置的影响,使其能够始终运行在计算好的正确的路线上。而且部队输入参数进行任何更改,行进是通过更改出租车对象自身位置属性达到的。

  改进如下

/**
 * @REQUIRES: p.x>=0 && p.x<=79 && p.x>=0 && p.y<=79
 * @MODIFIES: None
 * @EFFECTS: (int x, y; (x==(\old)this.x-1&&y==(\old)this.y) || (x==(\old)this.x+1&&y==(\old)this.y) || (x==(\old)this.x&& y==(\old)this.y-1) || (x==(\old)this.x&& y==(\old)this.y+1))
 *          && (Distance[x][y] == Distance[(\old)this.x][(\old)this.y]-1)==>(this.x==x && this.y==y)
 */

3.

/**
 * @REQUIRES: None
 * @MODIFIES: None
 * @EFFECTS: (findMaxCredit(r).size>1)==>(find_nearest(r, availiable_taxis).size>1)==>\result find_nearest(r, availiable_taxis)[0]
 */

  这部分代码是请求线程的核心组成部分之一。具体工作内容是当指令的时间窗口度过之后选择一个最佳的抢到单的出租车进行派单。和第一个方法相同的是参数数部份同样有一个指令,而且代码部分同样没考虑指令指向空的情况。我认为后置条件部分使用自然语言能够使方法描述更简洁。

  改进如下:

/**
 * @REQUIRES: r!=null
 * @MODIFIES: None
 * @EFFECTS: \result = taxi && (the first taxi found has max credit and is the nearest)
 */

4.

/**
 * @REQUIRES: request!=NULL && Main.requestsQueue!=NULL && Request_pattern!=NULL
 * @MODIFIES: Main.requests
 * @EFFECTS: (!request.matches(Request_patern))==> print "Wrong Input_LoadRequest()"
 *              call setRequest()
 *              tmpr = return value of setRequest()
 *              (tmpr.getSrc().x==tmpr.getDst().x && tmpr.getSrc().y==tmpr.getDst().y) ==> \result
 *              (isEqual(tmpr)) ==> Main.requestQueue.contains(tmpr)
 *              call Main.gui.RequestTaxi()
 */

  这部分代码使是输入处理线程的核心组成部分之一。具体工作内容是Load指令初始化程序时初始指令的加载和之后控制台输入指令的处理。两部分工作有很大的相同点因此我给他们抽象出来了同一个方法。方法的输入参数是一个字符串,方法中有对字符串各种形式的判断,因此前置条件关于字符串的部分可以省略。其次并没有对输入参数做任何的更改因此没有副作用。这部分规格书写的后置条件部分,大致写成了算法实现。

  改进如下:

/**
 * @REQUIRES: None
 * @MODIFIES: None
 * @EFFECTS: (!request.matches(Request_pattern))==>print "Wrong Input_LoadRequest()"
 *          (request.matches(Request_pattern))==>Main.requestsQueue.contains(request object which has the information of the input request)
 */

5.

/**
 * @REQUIRES: None
 * @MODIFIES: this.x, this.y, state
 * @EFFECTS: this.x == p.x && this.y == p.y && this.State == state;
 */

  这部分代码比较简单,是Load初始化命令时调用的用于设定出租车初始位置和出事信用值的线程安全的方法。输入参数是一个Point类型的对象p,和一个int类型的状态值。方法代码中并没有对任何上述参数进行正确性验证因此前置条件部分需要改进。此外方法中同样没有对任何输入参数进行更改,所以副作用部分有错误。

  改进如下:

/**
 * @REQUIRES: p.x>=0 && p.x<=79 && p.y>=0 && p.y<=79 && state>=0 && state<=3
 * @MODIFIES: None
 * @EFFECTS: this.x == p.x && this.y == p.y && this.State == state;
 */

四、聚焦关系


五、心得体会

  总的来说,这三次作业比中期的三次作业要好写很多,一个很大的原因是有了中期三次作业对多线程编程的锻炼。在代码设计上有了很大的提高之后进行编写事半功倍。这三次作业是本学期OO课程中最后的一个编程周期了,一共的九次训练,我的编程能力真的有了非常大的提高,从设计上到代码的编写方式上,现在回头看第一次多项式作业的代码真的可以说的上是惨不忍睹,很多地方情况的遗漏,算法实现上的各种妥协等。学习过程是痛苦的,编程过程是痛苦的,测试过程也是痛苦的,不过最后真的是值得的。

原文地址:https://www.cnblogs.com/NULL233/p/9095916.html

时间: 2024-11-10 19:52:00

OO第三次博客的相关文章

oo第三次博客总结

1.规则化发展历史 形式化方法的研究高潮始于20世纪60年代后期,针对当时所谓"软件危机",人们提出种种解决方法,归纳起来有两类:一是采用工程方法来组织.管理软件的开发过程:二是深入探讨程 序和程序开发过程的规律,建立严密的理论,以其用来指导软件开发实践.前者导致"软件工程"的出现和发展,后者则推动了形式化方法的深入研究.经过30多 年的研究和应用,如今人们在形式化方法这一领域取得了大量.重要的成果,从早期最简单的形式化方法一阶谓词演算方法到现在的应用于不同领域.不

OO第三单元博客总结

原文地址:https://www.cnblogs.com/xiongmaoage/p/10903350.html

第三版博客装订完毕

html: <div class="header"> <div class="wrap"> <div class="logo"> <a href="http://www.cnblogs.com/qiuge227/"> <img src="http://images.cnblogs.com/cnblogs_com/qiuge227/565381/o_logo.png

第三周博客问题总结

1.学会了```的用法 一开始并没有成功,后来发现是因为输入法没有切换成英文,今后这样的问题要避免出现.--20145106 2.问题:教材86页,Guess的代码,猜数字,不知道原先没有设定好一个数字,为什么可以在0-9之间猜中一个数 解答:百度了(Math.random()10)这行代码的意思,知道了(Math.random())的意思是在[0,1)之间随机产生一个数字,10,所以变成了[0,10)之间随机产生一个数字,所以可以进行猜数字 --20145123 3.IntegerCache.

第三版博客修改计划

为了让自己在学习中不断进步,随时保持学以致用的心态是尤为重要的.这样,一来让人有一种成就感的同时,也有一种满足感. 二来让你永远保持着一种心态,那就是谦逊,释然. 什么是进步,进步就是在每天的点点滴滴中,有所获,有所得. 什么是付出,付出就是每天你都知道自己在做什么,为什么要做,并为之努力的做. 什么是收获,收获就是即使你看不到它微小的变化,但在不知不觉中让自己仿佛变了一个人似的. 记得,记忆中感受最深的一本书是斯宾塞·约翰逊著作的<谁动了我的奶酪?>(Who Moved My Cheese?

第三次博客

第三次博客 一. 规格发展历史 从20世纪60年代开始,就存在着许多不同的形式规格说明语言和软件开发方法.在形式规格说明领域一些最主要的发展过程列举如下: 1969-1972 C.A.R Hoare撰写了"计算机编程的公理基础(An Axiomatic Basis for Computer Programming)"和"数据表示的正确性证明"两篇开创性的论文,并提出了规格说明的概念. 1974-1975 B.Liskow/S.N. Zilles和J. Guttag引

Android 博客园客户端 (三) 博客列表和内容显示

项目地址:https://github.com/ZhangTingkuo/AndroidCnblogs.git 经过很多天的努力,终于完成了博客界面的三个Fragment列表显示,分别是,首页.推荐.阅读排行.其实,距离上次,并没有增加更多的功能. 下一步,添加新闻界面的列表和内容显示.

第三次博客总结

一.规格化设计对的发展历史 在1968年,荷兰教授E.W.Dijkstra提出了"GOTO语句是有害的"观点,指出程序的质量与程序中所包含的GOTO语句的数量成反比,认为应该在一切高级语言中取消GOTO语句.这一观点在计算机学术界激起了强烈的反响,引发了一场长达数年的广泛的论战,其直接结果是结构化程序设计方法的产生.80年代中后期,面向对象程序设计逐渐成熟,被计算机界理解和接受,人们又开始进一步考虑面向对象的开发问题.这就是九十年代以Microsoft Visual系列OOP软件的流行

oo第四次博客总结

一.测试与正确性论证差异对比 测试,顾名思义,就是用一些有意义或无意义的输入去检测程序的正确性或鲁棒性,因其直观明了所以在写简单的程序时我们能迅速找出bug并加以解决.并且,这种方式是绝对客观的,只要和正确结果不匹配那么程序就一定存在一些问题.测试最大的缺点便是无法完全覆盖所有情况,即使很大的测试数据也可能跑不出来某些细微的bug,但这种bug有可能是致命的. 正确性论证则是从代码逻辑角度去分析代码,它的好处便是可以完全覆盖程序的所有情况并加以分析,只要分析不出错就能保证程序不出错,但这种方法的