接着继续(OO博客第四弹)
、测试与JSF正确性论证
测试和JSF正确性论证是对一个程序进行检验的两种方式。测试是来的最直接的,输入合法的输入给出正确的提示,输入非法的输入给出错误信息反馈,直接就能很容易的了解程序的运行情况。但是,每次测试只是在程序涉及的整个问题空间取一个元素进行测试,一次测试只能确保程序对于测试中的样例和同类样例是正确的,并不能确保全局正确性。而为了追求全局覆盖性,就需要大规模的测试样例轰炸了,但是这时测试的最致命缺陷就出现了,一是如何构造如此大量且属于不同类别的测试样例,二是如何确保构造的测试样例能够覆盖所有的语句和分支,三是对于一些复杂的,可靠性要求高的程序,这样的测试级别还不够,还需要更高级别的组合测试,例如,现在有两个分支1和2,分支1有a,b两种情况,分支2有c,d两种情况,单纯的分支测试只会保证a,b,c,d都被执行过,但对其中的组合情况没有考虑,而这正是实际问题中bug容易发生的地方,多重分支的叠加最后达到一个编程人员在设计很难预料到的情形,从而发生错误,而组合测试就需要将可能发生的组合:ac,ad,bc,bd全部测试一遍,而随着问题规模的扩大,测试样例的数目将呈指数级上升,这将带来非常大的测试难度。
正确性论证是一个上限很高的方法,如果能够完整且正确地对一个程序完成论证,那么这样分析过后的程序的可靠性几乎是100%,能够归纳覆盖整个问题空间。但是,正确性论证对于使用者的要求很高,一些复杂的论证需要很高的数学技巧,论证多分支情况时也很难保证完全不出错误不发生遗漏,这需要使用者对于该程序有非常高的熟悉度和强大的全局驾驭能力。此外,正确性论证需要的步骤很多,需要严格的证明,且主要是人来完成,因此需要大量的时间。同时,面对多分支组合问题,论证时也将面对指数级增长的划分数,这导致工作量会变得更大,非常消耗时间。
因此,我认为更合理的方式是结合两种方法,即使用正确性论证的思想来进行划分,对于每一个划分的情况构造通用性高的测试样例进行测试,最终得到具有高覆盖率的测试集。同时,应该做到测试与设计并行,在设计时也要适当考虑测试因素,对每个类和方法做更多的规约和异常检测,减小问题空间的维度,为测试减小压力。
二、OCL语言 VS JSF
OCL语言介绍:OCL(Object Constraint Language)语言,即对象约束语言,通常与UML一起使用,用来表达对于UML图的约束,而一个约束就是对一个(或部分)面向对象模型或者系统的一个或者一些值的限制。
二者相同点:
(1)都是声明式语言(Declarative),即表达式仅仅描述了应该去做"什么",而不是应该"怎样"去做。因为OCL是宣言式语言,所以UML中的表达式被提升到了纯建模的领域,而不必理会实现的细节和实现的语言。JSF也是说明了方法执行前后产生的影响,而不描述具体是如何产生影响的。
(2)都是基于数学(集合论和数理逻辑),取数学符号和自然语言的折中方案,使用逻辑表达式来描述约束内容,但是具体的元素可以使用自然语言说明。
(3)都有不变式,前置条件,后置条件这样的语法。
不同点:
(1)OCL是强类型语言,任何表达式的值都是属于一个类型的。这个类型可以是预定义的标准类型例如Boolean或者Integer,也可以是UML图中的元素例如对象。也可以是这些元素组成的集合,例如对象的集合、包、有序集合等等。JSF中对此没有很严格的规定和要求。
(2)OCL规定了很多具体的操作符,数据类型和表达式语法,而JSF中更着重于一定要按照逻辑运算规则进行推理,更加要求符合数理逻辑中的规则,而对于操作符没有很严格的要求。
(3)OCL语言可以对类,类的属性和操作等等任意的进行约束,而JSF仅针对类和方法。
(4)OCL通常结合UML类图使用,加之其支持对于各种上下文的约束,同时还要保证没有二义性,由于需要支持这么多的功能,所以它是一门“重型”语言,不像JSF是轻量化的语言。
三、第十四次作业相关UML图
UML类图
顶层package
package:helper
package:interface
package:model
package:model中Elevator类
package:model中QuestQueue类
package:model中SchedulerAI类
顺序图
四、总结
4.1本学期OO的四个模块内容
- (1) Java与对象(java速成+面向对象程序设计入门)
- (2) 并发与安全(多线程程序设计入门)
- (3) 抽象与规格(规格化和设计方法学入门)
- (4) 测试与论证(单元测试+JSF论证)
首先,四个模块是循序渐进,将整个工程化设计的内容划分成几大部分,然后分部分进行学习和训练。从大家最熟悉的程序语言开始,一步步深入到面向对象程序设计思想,多线程程序设计方法,直到工程设计方法,整体类似于一个自底向上的过程。但是呢,个人观点,在讲课的时候固然分成四个模块逻辑清晰,但是实际应用中四个模块的方方面面都是要涉及的,是否可以设计一些单元之间内容交互的作业,或者是综合作业,这样更具有综合性的东西才会更加让人感受到工程化方法的重要性,否则每次只针对一个点会让一些人可能产生应付该次作业的心态,当然这样的综合作业时间周期可以加长,专项作业中穿插综合作业,我觉得是更有意义的选择。
4.2个人收获与感悟
作为一个从大学开始接触编程的人,前一年半基本上是在面向过程语言中度过,写了数不清的C代码,所以很多时候脑子里有很多C语言的设计思想,经常会想java中是如何提供这个语法功能的。本学期接触面向对象程序设计,最大的感受就是:原来编程语言相关的设计和思想这么精彩。先说个人的程序吧,首先呢,得益于几位大佬的帮助和课程的训练,代码能力上取得的进步是最大的,从命名规范,书写格式,数据结构,类和方法的设计,再到线程的规划与管理,都有了长足的进步。当然肯定要贴图对比才最直观了:
第一次作业:
如果硬要评价的话,这次作业就是满满的C味java,完全是C语言的设计思想,只不过假装建立一个类调了java类库的一些方法而已。
那么到了第十一次作业:
编程规范上已经有了长足的进步,同时也学会使用java的一些更加高级的语法,最重要的是,真正使用面向对象的思想来建模,逐步使用接口来对设计进行规划。
到了最后一次代码作业,即第十四次作业,即重构ALS电梯时:
代码风格已经趋于稳定,算是比原来的自己上了一个大台阶吧。
关于文档和规格,其实我一向是非常支持注释和文档的书写,代码写的简洁高效易读,同时辅以良好的注释和说明文档,就像自己写的一篇文章一样。不过说实话,我对于以JSF这种方式进行规格撰写是不太支持的,我个人偏向于java类库中那种javadoc的格式,这个想做到自动化太难了,从理解的直观性来说,自然语言是要好过逻辑语言的,如果我们在设计上加以优化,二义性的问题也能得到很好解决,JSF的优势是能覆盖到问题的各个方面,绝无二义性,所以个人觉得也可以适当把JSF补充在可能出现二义性的地方。不过,规格书写的重要性,或者更深层次,设计规约的重要性,我在第十四次作业中得到了非常良心的体验。在进行JSF论证之前,我对之前的代码进行了彻彻底底的重构,自认为已经很完美了。但是在进行论证的过程中,仍然发现了几处很难表述的方法,而之后通过对划分执行情况,再对代码作进一步分析后发现,我的设计思路中有很多交叉和冗余地方,比如明明可以通过维护队列完成的功能,我在之前的设计中却给队列元素增加了两种标记,标记之中还有小的分类,致使代码功能虽然正确但是很臃肿,而通过论证时对于各类情况的剖析与划分,便能很容易的找出问题的原因所在,这也再一次告诫我,一定要设计优先,不要直接上手写代码。
关于设计问题,我大约经历了这样一个过程:面向过程——无脑使用类,方法当函数用——抽象类+接口设计。仅凭大脑思考,基本是不可能驾驭大工程的,那么通过设计方法学来首先做设计规约,并把所有的设计思路具象化,在java中使用抽象类+接口设计的方式进行初期规划,并辅以文档和规格进一步对类和方法进行规范化,做完所有准备工作之后再开始写代码,这样,才能真正写出大工程。
测试是我的一个很严重的弱项,老实说现在还处于对拍器对比输出结果的阶段。本学期初步接触了单元测试,但是感觉理解的还很不足,个人认为这部分内容最重要的还是在实际中使用,为了完成作业去编写单元测试意义不大,因为测试的代码基本上都是已经修复完bug的版本,少了测试——发现bug——修复bug——再测试这一环节,就很难深刻体会到单元测试的优点,这部分内容结合在复杂的几次作业中就更好了。
4.3 工程化方法之我见
工程化方法包括很多的内容,一一说下来要列好长的清单,其实核心就在于如何解决个人有限的能力和工程无限大的复杂度的矛盾。实际工作中大工程需要很多人来合作完成,而每个人的能力,特点又不可能相同,所以1+1=2是绝对不可能的,那么如何在这样的情况下,尽可能的追求总体的最终的高效率和高质量,这就是工程化方法告诉我们的事了。当然,现在的工程化方法大多是建立在人的经验之上的。说不定到了未来,由于编程人员能力的提高(或者说机器自动生成底层代码),相关数据分析能力的提高,工程化方法将变成数据导向的产物,人类的思考只需做最高层的设计。毕竟,最核心的永远是解放生产力,让人的思考用到最关键的地方去呀。
4.4 关于OO
关于OO课程,首先表示非常感谢这门课程,确实给我带来了很多变化。这门课程虽然被很多人诟病,但是我觉得还是很有其存在必要的,只是一些具体实现的环节仍然存在问题,因此,我希望能成为OO助教,真正去修补这些问题,而具体的建议,就通过实际工作来看吧,OO接着继续!
接着继续(OO博客第四弹)的更多相关文章
- 设计与实现分离——面向接口编程(OO博客第三弹)
如果说继承是面向对象程序设计中承前启后的特质,那么接口就是海纳百川的体现了.它们都是对数据和行为的抽象,都是对性质和关系的概括.只不过前者是纵向角度,而后者是横向角度罢了.今天呢,我想从设计+语法角度 ...
- BUAA_OO_博客作业四
BUAA_OO_博客作业四 1 第四单元两次作业的架构设计 1.1 第13次作业 类图 作业要求:通过实现UmlInteraction这个官方提供的接口,来实现自己的UmlInteraction解 ...
- OO博客总结——OO落下帷幕
OO博客总结--OO落下帷幕 凡此过往,皆为序章. 不知不觉OO课程即将落下帷幕,一路坎坎坷坷磕磕绊绊,可算是要结束了,心里终于松了一口气,也有小小的不甘和遗憾.凡此过往,皆为序章.特殊的线上OO课程 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(四)-使用Travis自动部署Hexo(2)
前言 前面一篇文章介绍了Travis自动部署Hexo的常规使用教程,也是个人比较推荐的方法. 前文最后也提到了在Windows系统中可能会有一些小问题,为了在Windows系统中也可以实现使用Trav ...
- [置顶] CSDN博客第四期移动开发最佳博主评选
CSDN博客第三期最佳移动开发博主评选圆满结束,恭喜所有上榜用户,为继续展示移动开发方向优秀博主,发掘潜力新星,为移动开发方向的博客用户提供平台,CSDN博客第四期移动开发最佳博主评选开始.同时,获奖 ...
- Django搭建博客网站(四)
Django搭建博客网站(四) 最后一篇主要讲讲在后台文章编辑加入markdown,已经在文章详情页对markdown的解析. Django搭建博客网站(一) Django搭建博客网站(二) Djan ...
- Django 系列博客(四)
Django 系列博客(四) 前言 本篇博客介绍 django 如何和数据库进行交互并且通过 model 进行数据的增删查改 ORM简介 ORM全称是:Object Relational Mappin ...
- thinkphp5项目--个人博客(四)
thinkphp5项目--个人博客(四) 项目地址 fry404006308/personalBlog: personalBloghttps://github.com/fry404006308/per ...
- OO博客作业-《JML之卷》
OO第三单元小结 一.JML语言理论基础以及应用工具链情况梳理 一句话来说,JML就是用于对JAVA程序设计逻辑的预先约定的一种语言,以便正确严格高效地完成程序以及展开测试,这在不能容忍细微错误的工程 ...
随机推荐
- 最新Flume1.7 自定义 MongodbSink 结合TAILDIR Sources的使用
Flume MongodbSink 此mongodb支持3.0 github地址 MongodbSink flume-ng-mongodbsink An Apache Flume Sink that ...
- iPhone将NSString转换编码集为gb2312或者gbk的方法
很多时候软件读取的中文网页编码集是gb2312,所以显示出来的是乱码.这时需要将NSString文字编码转换.你可以试试以下代码 NSURL *url = [NSURL URLWithString:u ...
- mysql 系统用户最大文件打开数限制
纸上得来终觉浅,绝知此事多宕机...记录一下自己很蠢的一次故障处理过程. 上周的时候,一个刚上线的系统又开始反映登不上了,因为最近这个系统也老是出现这个问题,开发也一直在找问题中,所以也没太在意.于是 ...
- Linux下onvi支持h265环境的的搭建:gsoap的安装及生产.c .h文件
1. 下载gsoap :http://www.genivia.com/products.html#notice,既Open Source gSOAP版本,并解压进入目录安装,configure后面 ...
- jQuery Nestable2 使用总结
最近,因为公司的一个新项目,用了一个基于bootstrap二次改造的国外友人的框架.感觉很一般吧,要求更换框架,客户拒绝.只能搞这个,发现里面一个jQuery插件-[Nestable]但是源作者长时间 ...
- PHP/Laravel轻松上传超大文件
我们知道,在以前,文件上传采用的是直接传整个文件的方式,这种方式对付一些小文件是没有问题的.而当需要上传大文件时,此种方式不仅操作繁琐,需要修改web服务器和后端语言的配置,而且会大量占用服务器的内存 ...
- 【10.21总结】一个渗透测试练习实例——发现未知的漏洞(Race condition)
Write-up地址:Exploiting an unknown vulnerability 作者:Abhishek Bundela 这篇文章跟我之前看到的文章不太一样,作者是按照一个练习的方式简单描 ...
- 十张图了解Docker【转】
这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(container)和镜像(image)之间的区别,并深入探讨容器和运行中的容器之间的区别. 当我对Docker技术还是一知半解的时候,我 ...
- JSON解析工具——Jackson的简单使用
什么是Jackson 可以轻松实现Java对象与JSON字符串的转换 准备工作:导包 Jackson的jar all下载地址:http://jackson.codehaus.org/1.7.6/jac ...
- 【转载】COM 组件设计与应用(十六)——连接点(vc.net)
原文:http://vckbase.com/index.php/wv/1257.html 一.前言 上回书介绍了回调接口,在此基础上,我们理解连接点就容易多了. 二.原理 图一.连接点组件原理图.左侧 ...