进度:第五周
讲义 E4
在开始本练习之前,我们建议你仔细阅读整个问题。
介绍
在本练习中,你将应用一些技术来改进软件质量。你需要使用上周所完成的图的设计与实现作为本练习的例子。
你将使用对象模型来捕捉图的设计和实现中的至关紧要的不变式, 你将记录表示不变式(representation
invariant或者rep invariant)和抽象函数,还将以方法的形式实现它们。你将编写运行时断言来检查先决条件、表示不变式以及其他重要的内部不变式。
在完成这些之后,你将很好的发现代码中的错误。通过本练习,你还可能发现改进表示或者规格说明的方法。你应该做好重写大部分代码的准备,但是代码应该不是太多,所以这并不是很大的负担,而且比重写代码能更有效的改进编程技巧的方法并不多。
创建对象模型需要进行很多练习,在熟练之前它带来的负担要比它的好处多。因此本练习的第一个问题就是创建一些简单、为人们所熟知领域的小型模型。到目前为止,你只看到了对象模型的代码形式,这当中的一组对象描述了Java™对象,而属性描述了实例变量。在这些面向问题的模型中,面对现实世界中的对象以及它们之间的关系,你的思考必须更加抽象一些。你可能需要阅读课程讲义关于“数据模型”中的材料作为本练习的基础。
问题 1:对象模型初探
[15 分]
为下列领域分别创建一个对象模型。对于每种情况,画一张图,并添加图中不容易表达的约束的文本描述。不需要考虑易变性。
- 一副纸牌,其中除小丑外每一张纸牌应该有数字和花色。任意两张纸牌不能有相同的数字和花色。
- 一个命题公式是一个与-公式,或者一个或-公式,或者一个非-公式,或者一段文字。与-公式和或-公式是命题公式的排列,非公式就是一个命题公式。
- 国家领空被划分为多个区域,称为centers,每个center有一个管理员并被划分为多个部分。每个空中交通控制器分派给一个部分。
- 一本书有前言、一章或者更多的章节,还有可能拥有一个目录。目录将书中各个主题的名字和它们的页码关联起来,且目录中不包含前言和目录自身的页码。
- 一个学位规划由一系列的课程组成。其中包含了很多的主修方向,每个主修方向有一门主修课程和一门或多门选修课程。一门课程可能会有先决课程:在学习此课程之前必须完成的课程。一个课程所属的学位规划通常也包括此课程的先决课程。一个课程不能作为自己的先决课程。
问题 2:图形不变式
[50 分]
创建以下项目:
一个在规格说明抽象级的图类型的抽象对象模型。
也就是说,模型中的方法对于你的类型的客户端应该是可见的。
一个在实现级别的图类型的具体对象模型。也就是说,这个模型应该包含所有表示中的对象。请确定你的模型包括了对象共享的信息、易变性信息以及关于哪些引用可能为空的信息。
图中的表示不变式应该是一个与具体对象模型相一致的文本形式的约束。指明你的表示不变式中哪些属性在具体对象模型中也捕捉到了的,以及哪些在具体对象模型中出现了的属性却没有包含在你的表示不变式中。剪切类的相关描述(以及其他的属于表示的相关类)并将它们与不变式粘贴在一起。
图的一个抽象函数,它应该说明如何从具体对象模型中获得一个抽象对象模型的实例。
一个表示不变式的实现,实现一个名为repCheck的方法,它没有参数、返回值为空,并且当违反不变式时抛出一个异常。这个方法并不需要检查不变式的所有属性,你需要从工程的角度决定对哪些属性进行测试是可行的。你不需要考虑这个方法的执行是否会对图的实现的性能造成影响。
一个抽象函数的实现,实现一个名为toString的方法。返回的字符串的抽象值必须严格遵守你的抽象对象模型和抽象函数的描述。
一个问题列表(如果有的话)。列出通过对以上项目的思考,在你的代码中发现的问题。
问题 3:图的测试 [30 分]
完成你的图的代码,通过对repCheck方法的调用以及运行时断言检查其它你希望在代码中遵守的重要的不变式。
为你的图创建一组测试。通过对规格说明和实现的考虑来选择你的测试用例。你的测试应该能够覆盖程序中所有的分支,并且应该覆盖规格说明中出现的所有边界情况。尽量不要使用并不需要的测试用例。
使用JUnit运行你的测试,并报告运行的结果。
你应该提交:
你的代码的一个新副本,它应该使用了新的断言、并修改了你在你的分析中所发现的问题。
你所作的一组测试。标明哪些测试用例提供了对哪些功能的覆盖。
一个问题列表(如果有的话),列出在运行测试后你所发现的你的代码中的问题。
一段说明,指出哪些测试成功运行了。如果遗漏了这个,我们将假设你的测试都没有成功。
问题 4:对T建模 [5 分]
波士顿地铁(“T”)并不只是一个以车站为结点、以铁轨段为边的图。你会发现你所做的基于一般图的程序,并不能处理“T”中的一些特殊情况。如果你为现实中的MBTA开发一个程序,你就应该考虑以上的这些问题。一个好的开始应该是建立一个能够捕捉“T”的结构以及“T”上面旅程的对象模型,接着你就能够以此为基础来设计一些抽象数据类型。
创建这样一个对象模型,它应该表明一段旅程包含多个阶段的事实,而每一个阶段应该是一个单独路线上的一系列的铁轨段。它还应该提供乘车帮助,例如对于Green
Line给出应该乘坐哪趟列车才能到达Park Street。
问题&回答
这部分将对练习中一些常见问题进行澄清和回答。我们将尽力保持对这部分的更新,因此,当你遇到问题时这部分应该是你最先查看的地方(在仔细的阅读问题描述讲义和规格说明之后)。