【面向对象设计与构造】第四次博客作业
一、测试与正确性论证的效果差异
软件测试是在规定的条件下对程序进行操作,以发现程序错误,衡量软件品质,并对其是否能满足设计要求进行评估的过程。简单来说,测试就是一种对程序的实际输出与预期输出之间进行审核或比较的过程。
这种对程序正确性进行评估的方法其优点在于简单、直观,能通过少量的测试数据来对程序的基本功能是否正确做出判定,尤其是对于一些规模较小的程序来说,甚至可以通过有限的测试数据对程序所要处理的所有情况进行全方位的覆盖,例如我们最初几次作业中的多项式,单线程电梯等规模较小、输出确定的程序,就可以通过足够的测试对其进行全方位的覆盖。
但这种方式的缺点也是十分明显的,荷兰计算机科学家Dijkstra曾经说过:“测试只能表明程序中存在错误,而不能说明程序中没有错误。”随着计算机技术的发展,软件规模的不断增大已经成为必然的趋势,当软件规模达到一定程度时几乎不可能通过有限的测试覆盖所有情况,智者千虑,必有一失;且因为多线程等原因,很多输出具有不确定性,很多bug也难以通过简单的测试复现;对于一些特殊情况,如果测试的时间、空间复杂性过高,在实际测试中也是不可行的。这时就需要一种能够从理论的层面对软件的正确性进行论证的方法。
正确性论证是从代码逻辑等层面论证程序达到预期目的的一般性陈述,而该论证与程序输入数据的特定值无关,能够代表穷举性测试。应用数学方法或数学工具来对程序进行抽象和论证,是从根本上解决程序正确性问题的一个重要途径。形式化方法是程序正确性论证所追求的一种方向,形式化方法的难点在于如何从具体的程序代码抽象出一种统一、精确的形式规约,其局限性在于所处理的问题必须是可判定的。不可否认的是,这种论证往往也需要花费较多的时间和精力,且随着软件规模的增大,论证的难度也在急剧上升。
总之,测试和正确性论证论证是对软件的正确性和可靠性进行评估的两种重要的方法,二者都是不可或缺的,不能为了追求正确性论证就忽略测试的重要性,比如单元测试也是软件开发过程中的一个重要环节,应根据具体的情况选择合适的方法,才能取得最好的效果。
二、OCL语言
对象约束语言(Object Constraint Language),简称OCL,是UML标准的一部分,可以用来更好地定义对象的行为,并为任何类元指定约束。OCL语言对UML中图形或其他组件都没有控制权,它只是在使用时返回值。OCL语言并不能修改对象或系统的状态,它只是一种无任何副作用的声明性语言,用来指示对状态的修改何时发生,所有有关实现的问题都不能用OCL来表达,同时也不能用OCL编写程序逻辑和控制流程。另外,OCL是一种类型化语言,即OCL中的每个表达式都是具有类型的。
与JSF规格相比较,二者的相同点在于
(1)都试图通过对对象不变量、前置条件、后置条件等的描述和限定来限定对象的行为,达到规范设计要求的效果;
(2)二者的内容都是描述性的,只是对于对象或系统状态的描述,而不会对其进行任何修改。
二者的不同点在于
(1)OCL语言规范更加详细和完善,不仅定义了基本类型和集合类型,还定义了关键字、表达式语法等,而目前我们的JSF语言对许多细节的规定和要求并不是很明确;
(2)OCL语言在一定程度上是对自然语言和数学语言的折中,因此适应范围更加广泛;而我们的JSF语言许多情况难以使用谓词逻辑语言准确描述,使用自然语言描述时又过于宽泛,容易产生二义性,这二者之间的矛盾是限制JSF使用范围的一个重要因素。
三、类图、顺序图、状态图
类图
顺序图
状态图
针对电梯的三个不同状态及其相互转化,画出的状态图如下:
四、学期总结
1. 四个单元模块知识点之间的关系
第一单元主要学习java语言及面向对象编程的基本知识,如对象、继承、多态、抽象等重要概念;
第二单元主要学习多线程编程及线程的安全机制等内容,还引入了面向对象程序的需求分析与设计原则;
第三单元主要学习规格化设计,主要涉及过程抽象与异常处理、数据抽象、类型层次规格与迭代等;
第四单元主要涉及基于规格的程序测试及正确性论证的相关内容。
可以看出,理论课程的内容体系总体是比较完整的,基本涉及了面向对象软件开发的主要过程,且课程内容的安排也是由浅入深、循序渐进、呈阶梯状上升的,每一部分的内容都是后续学习的基础,这就要求我们从一开始就应该认真对待每一次课的学习。
2. 收获与进步
本学期我们的编程作业内容主要包括多项式、电梯调度、文件监控、出租车调度这四部分,难度也是不断增加的。作业的重点在于电梯调度与出租车调度这两部分,每一部分的内容也分为了多次作业,需求不断增加。
这样的训练模式使得我们每次进行设计时都不能仅仅局限于本次作业的需求,更应该充分重视程序的可维护性与可继承性,为今后的维护和修改带来方便。
程序的测试与程序的质量是直接相关的,测试是检验程序质量的最直接的方式。每次的互测扣分模式使得我们不得不重视自己程序的质量,同时为了尽可能多得一点分也会穷尽各种测试手段来检查对方的程序。所以不得不说这种互测模式或者分数是推动提高程序质量,丰富测试手段的根本动力。
同时也应该注意到没有bug仅仅是高质量程序的一个最基本的要求,在此基础上,程序的质量还与代码风格、框架设计、可维护性等许多方面都有重要的关联,这也是我们课程内容后半部分训练的重点之一。
3. 对工程化开发的理解
我认为工程化开发是在软件规模不断增加的背景下所产生的一种必须的软件开发方式。将软件开发作为一项工程来看待,就要求我们不仅仅只是实现自己程序的功能,更要着眼于整体,考虑与他人的合作,考虑自己的代码是否满足高内聚、低耦合的要求,是否能够被他人理解与维护,这就对个人的程序开发提出了更高的要求。
4. 期望与建议
这门课在目前在这种互测模式下的一个重要问题在于对于互测的规范和要求不够详细与完善,某些bug到底该不该扣,某些jsf书写到底算不算错,都没有明确的标准,这只能导致测试者在互测时会根据自己的理解去扣分,或者自己完全不去理解只根据助教的理解去扣分,而每个人的理解都不是相同的,每个助教的理解也可能是不同的,这就导致出现了很多无意义的“交流”。一项制度不论是否合理,只要他本身的规定足够清晰和详细,不会朝令夕改、模棱两可,就可以被多数人所接受。在无法取消互测制度的前提下,还是期望课程组能够多花时间完善下jsf的规格的详细规范,尽量明确和统一一下互测标准的问题。
另外这种分班级建多个微信群的方式,我认为是不合理的,很容易导致信息不同步、各班要求不统一的问题,也增加了许多无意义的“交流”。