软件构造lab2
1 实验目标概述
本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象
编程(OOP)技术实现 ADT。具体来说:
⚫ 针对给定的应用问题,从问题描述中识别所需的 ADT;
⚫ 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
⚫ 根据 ADT 的规约设计测试用例;
⚫ ADT 的泛型化;
⚫ 根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示
(representation)、表示不变性(rep invariant)、抽象过程(abstraction
function)
⚫ 使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表
示泄露(rep exposure);
⚫ 测试 ADT 的实现并评估测试的覆盖度;
⚫ 使用 ADT 及其实现,为应用问题开发程序;
⚫ 在测试代码中,能够写出 testing strategy 并据此设计测试用例。
2 实验环境配置
简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。
特别是要记录配置过程中遇到的问题和困难,以及如何解决的。
问题是:由于中文路径,idea自带的覆盖度测试插件无法直接运行
解决方式:参考csdn,修改jvm虚拟机的一些默认设置。
其他环境沿用之前配置好的。
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/HIT-Lab2-120L020509
3 实验过程
请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 Poetic Walks
要求实现一个抽象数据类型Graph来表示有向图,并实现一个GraphPoet类调用Graph进行单词的充填。
3.1.1 Get the code and prepare Git repository
通过git clone https://github.com/rainywang/Spring2022_HITCS_SC_Lab2克隆远程仓库,创建一个文件夹,将所需的文件复制进去,并执行git init命令初始化,使用git add .和git commit进行一次commit。
3.1.2 Problem 1: Test Graph <String>
要求实现GraphInstanceTest类,需要根据规约设计测试策略,并设计所需的测试数据。测试策略如下:
3.1.3 Problem 2: Implement Graph <String>
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
3.1.3.1 Implement ConcreteEdgesGraph
要求使用以下给定的数据结构表示一个图,并实现在图上操作的方法。
private final Set<String> vertices = new HashSet<>();
private final List<Edge> edges = new ArrayList<>();
设计的AF、RI等如下:
测试结果如下:
覆盖度为100%,如下:
3.1.3.2 Implement ConcreteVerticesGraph
要求使用以下给定的数据结构表示一个图,并实现在图上操作的方法。
private final List<Vertex> vertices = new ArrayList<>();
设计的AF、RI等如下:
测试结果如下:
覆盖度如下:
其中行覆盖率位94%,这是因为checkRep中不符合Rep的代码没有执行到。
3.1.4 Problem 3: Implement generic Graph<L>
3.1.4.1 Make the implementations generic
需要将String替换成L,包括以下语句等:
public class ConcreteEdgesGraph<L> implements Graph<L> { ... }
class Edge<L> { ... }
public class ConcreteVerticesGraph<L> implements Graph<L> { ... }
class Vertex<L> { ... }
不需要做其他改变。
3.1.4.2 Implement Graph.empty()
Empty方法只需要返回一个新的graph对象,即:
3.1.5 Problem 4: Poetic walks
3.1.5.1 Test GraphPoet
测试策略如下:
测试结果如下:
覆盖度如下:
3.1.5.2 Implement GraphPoet
要求实现的Poet的功能是在根据语料库在句子中插入单词,比如语料库中有连续的a b c,输入中有连续的a c,则输出在a c中间插入b。
需要对输入的字符串进行一些处理,生成单词的数组,并插入graph中。
3.1.5.3 Graph poetry slam
在Main中添加以下语句:
结果如下:
3.1.6 Before you’re done
请按照http://web.mit.edu/6.031/www/sp17/psets/ps2/#before_youre_done的说明,检查你的程序。
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在这里给出你的项目的目录结构树状示意图。
src
P1
graph
ConcreteEdgesGraph.java
ConcreteVerticesGraph.java
poet
GraphPoet.java
Main.java
Test.txt
mugar-omni-theater.txt
test
P1
graph
ConcreteEdgesGraphTest.java
ConcreteVerticesGraphTest.java
GraphInstanceTest.java
GraphStaticTest.java
poet
GraphPoetTest.java
3.2 Re-implement the Social Network in Lab1
要使用Graph<L>数据结构重新实现FriendshipGraph和Person类
3.2.1 FriendshipGraph类
需要调用graph的方法,来实现FriendshipGraph中所需的功能。
构造函数直接生成一个新的graph对象,addVertex、addEdge方法直接调用graph的方法即可,如下:
GetDistance使用广度优先算法,把遍历到的节点存在队列中,将与每个节点之间的距离存在Map中。每遍历一轮,距离加1。直到找到person2返回距离;或队列为空时仍未找到,返回-1.
3.2.2 Person类
Person类无需做出变化,沿用上一次实验的代码。
3.2.3 客户端main()
Main无需做出变化,沿用上一次实验的代码。
3.2.4 测试用例
测试用例大部分沿用上一次实验的代码,并作了一些小修改。
由于graph类的一些局限性,对一些非法输入没有做测试。
测试用例全部通过,且覆盖度为100%,如下:
3.2.5 提交至Git仓库
使用git remote add origin https://github.com/ComputerScienceHIT/HIT-Lab2-120L020509命令连接到github服务器,并使用git add .,git commit -m “finished”,git push命令提交并推送到github服务器。
在这里给出你的项目的目录结构树状示意图。
src
P1
graph
ConcreteEdgesGraph.java
ConcreteVerticesGraph.java
poet
GraphPoet.java
Main.java
Test.txt
mugar-omni-theater.txt
P2
FriendshipGraph.java
Person.java
test
P1
graph
ConcreteEdgesGraphTest.java
ConcreteVerticesGraphTest.java
GraphInstanceTest.java
GraphStaticTest.java
poet
GraphPoetTest.java
P2
FriendshipGraphTest.java
PersonTest.java
doc
Lab2-120L020509-Report.docx
lib
hamcrest-core-1.3.jar
junit-4.13.2.jar
4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
|
日期 |
时间段 |
计划任务 |
实际完成情况 |
|
5.22 |
18.00-24.00 |
初始化,完成3.1.2concreteedgesgraph及test |
按预期完成 |
|
5.25 |
18.00-24:00 |
完成concreteedgesgraph、concreteverticessgraph及test |
按预期完成 |
|
5.26 |
22.00-24.00 |
完成graph.Empty,完善之前内容 |
按预期完成 |
|
5.29 |
15.30-22.00 |
完善P1、完成P2 |
按预期完成 |
5 实验过程中遇到的困难与解决途径
|
遇到的难点 |
解决途径 |
|
对规约、AF、RI等的写法不熟悉
|
多看ppt,查看一些文档,学习相应的写法 |
|
由于中文路径,idea自带的覆盖度测试插件无法直接运行 |
参考csdn,修改jvm虚拟机的一些默认设置即可。 |
6 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
通过本次实验熟悉了面向ADT的编程,学会了规约、RI、AF等的书写,但面向ADT的编程与我原来的变成习惯不同,还需要一些练习才能更加熟悉。
6.2 针对以下方面的感受
(1) 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
直接面向应用场景编程对单个模块可能效率更高,但可复用性不好。面向ADT的编程可能更耗时,但编写完成后能够多次复用,在复用多的情况下反而能节省时间。
(2) 使用泛型和不使用泛型的编程,对你来说有何差异?
差异并不大,在代码上的区别只是将变量类型的普通声明换成泛型。使用泛型之后更加灵活,能够适应多种数据类型。
(3) 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
测试代码的编写无论是在编写核心代码之前还是之后,工作量是相同的,但编写完测试代码后能有助于测试代码的调试,提升效率。
(4) P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
当在多个场景下多次复用ADT时,可以减少重复的工作量。
(5) 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
能够在实现代码之前对需要实现的功能有一个比较全面清晰的认识,并防止一些不必要的bug出现。这样做能减少bug,减少不必要的调试时间,而且思路更清晰,愿意这么做。
(6) 关于本实验的工作量、难度、deadline。
工作量和难度适中,deadline正好与计算机系统考试重合,比较赶时间。
(7) 《软件构造》课程进展到目前,你对该课程有何体会和建议?
学习了这门课程,我对软件设计的工程性、系统性有了更深一层的认识,学会了软件成熟的开发流程。
建议:在课堂上再多举一些例子,否则一些部分定义较多,比较枯燥,不容易理解,也不容易记忆。
浙公网安备 33010602011771号