软件构造实验二

2021年春季学期
计算学部《软件构造》课程

Lab 2实验报告

姓名 史雨菲
学号 1190200205
班号 1903010
电子邮件 2878379161@qq.com
手机号码 19909218189

目录

1 实验目标概述 1
2 实验环境配置 1
3 实验过程 1
3.1 Poetic Walks 1
3.1.1 Get the code and prepare Git repository 1
3.1.2 Problem 1: Test Graph 1
3.1.3 Problem 2: Implement Graph 1
3.1.3.1 Implement ConcreteEdgesGraph 2
3.1.3.2 Implement ConcreteVerticesGraph 2
3.1.4 Problem 3: Implement generic Graph 2
3.1.4.1 Make the implementations generic 2
3.1.4.2 Implement Graph.empty() 2
3.1.5 Problem 4: Poetic walks 2
3.1.5.1 Test GraphPoet 2
3.1.5.2 Implement GraphPoet 2
3.1.5.3 Graph poetry slam 2
3.1.6 Before you’re done 2
3.2 Re-implement the Social Network in Lab1 2
3.2.1 FriendshipGraph类 2
3.2.2 Person类 3
3.2.3 客户端main() 3
3.2.4 测试用例 3
3.2.5 提交至Git仓库 3
4 实验进度记录 3
5 实验过程中遇到的困难与解决途径 3
6 实验过程中收获的经验、教训、感想 4
6.1 实验过程中收获的经验和教训 4
6.2 针对以下方面的感受 4

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 实验环境配置
简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。
特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/HIT-Lab2-1190200205shiyufei
3 实验过程
请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 Poetic Walks
建立一个Graph的抽象数据类型,并在此抽象数据类型的基础上实现写诗。
3.1.1 Get the code and prepare Git repository
Git clone
3.1.2 Problem 1: Test Graph

3.1.3 Problem 2: Implement Graph
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
该部分要求重写Graph里的方法,分别以点为基础的图和以边为基础的图。两种类型的图都经过同一个实例测试。

3.1.3.1 Implement ConcreteEdgesGraph
Edge类的实现
Edge的功能主要为存储边的3个信息。此外,为了Graph实现方便,增加了判断两条边是否相等的方法。
ConcreteEdgesGraph实现
该类以Edge为基础重写Graph,用集合来存储点和边(Edge),每有Edge的增加就会影响到集合的更改,而点的删除也需要在集合中查询匹配。

3.1.3.2 Implement ConcreteVerticesGraph
Vertex实现
Vertex是点的抽象类,包含3个信息:点的标识、指向该点的边、由该点引出的边。Vertex需要能访问这3个信息,以及增加/删除进边/出边。
oncreteVerticesGraph实现
ConcreteVerticesGraph是以点为基础的图,每个点通过唯一的标识进行区分,set和remove都依赖与Vertex类中的添加和删除操作,sources和targets也调用了Vertex类的方法。

3.1.4 Problem 3: Implement generic Graph
3.1.4.1 make the implementations generic
在程序中选择“重构”或选择“String”并选择更改所有匹配项(要注意toString),即可实现泛化类型。
3.1.4.2 Implement Graph.empty()
使Graph.empty()能返回一个新的空实例。代码如下:
public static Graph empty() {
return new ConcreteEdgesGraph();
}

3.1.5 Problem 4: Poetic walks
给定一个语料库corpus,根据corpus中的文本生成一个单词图,然后给定一条语句输入,在图中搜索词之间的关系,自动补全语句中可能可以完善的部分。
图的构建规则是,在corpus中,对每一个不一样的单词看作一个顶点,相邻的单词之间,建立一条有向边,相邻单词对出现的次数,作为这条有向边的权值。在输入信息补全时,对相邻单词A和B做检查,如果存在一个单词C,在图中可以由前一个单词A通过这个单词C到达单词B,那么就在A和B之间补全C,补全的优先级按照权值越大者优先。

3.1.5.1 Test GraphPoet
在基于预设的测试用例基础上,增加等价类划分的多种情况。
等价类划分:两个单词之间不存在连接词,两个单词之间只有一个连接词,两个单词之间有多个连接词。
此外还要注意句末的句号,测试当一个句子最后一个词是“桥”的一端。

3.1.5.2 Implement GraphPoet

  1. 表示不变量和检查不变量
    该应用中的不变量是所有的点都不为空。
  2. 构造函数
    用文件输入单词,String.split()分割为数组,通过String.toLowerCase()小写化。
    接下来构建图,相邻的单词加边。首先要在加边前通过Graph.add()加点,加边时要判断是否存在:由于Graph.set()能返回之前加的边的值,以此来判断是否存在,存在则在之前的值加一(之前的边的值保存为lastEdgeWeight)。
  3. Poem(String input)
    当相邻两个单词任意一个不在之前创建的图里,则将后者单词加入即可(再加个空格)当存在时,由于Bridge长度只能为2,所以:分别求两个单词的sources和targets,将该Map转换为Set求交集;若交集为空,则无桥,若交集不空,则在交集中找最短的桥(可以在Map的value中查询weight)。

3.1.5.3 Graph poetry slam
This is a the Mugar system Omni Theater sound system test of the.”,测试成功。

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
Graph.java
poet
GraphPoet.java
Main.java
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
这部分任务就是用我们在3.1中写的ADT,把第一次实验中的FriendshipGraph重新实现一遍,图中的节点仍然是Person类型,所以泛型L一律为Person. 而对于已经写好的FriendshipGraph中的方法,要用3.1中的Graph ADT中的方法来实现它们。

3.2.1 FriendshipGraph类
Graph graph:
直接调用Graph的静态方法.empty()生成一个空的图。
boolean addVertex():
直接调用graph.add()添加点。
int addEdge():
调用graph.set()两次,添加双向边,默认权值为1,并记录可能存在的旧边的权值。
int getDistance():
首先判断起止点是否相等。再新建Map<Person, Integer> dis表示从起始点开始到该Person的距离,以及Map<Person, Boolean> vis表示该Person是否访问过。将两个Map初始化后,把起点标记为已经访问(所有涉及这两个Map的操作均需要remove后再put,后文不再阐述)。然后开始BFS搜索,找到终点为止。

3.2.2 Person类
该类的目标是将每一个人对应到一个Person对象,并存储名字的信息。为了防止泄露,我将String Name设置为私有且不可变的。在构造函数中将Name初始化。

3.2.3 客户端main()
3.2.4 测试用例

3.2.5 提交至Git仓库
如何通过Git提交当前版本到GitHub上你的Lab3仓库。
在这里给出你的项目的目录结构树状示意图。
src
P2
FriendshipGraph.java
Person.java
test
P2
FriendshipGraphTest.java
4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 计划任务 实际完成情况
2021-6-11 18;00-20;00 P1 problem1-3 延期完成
2021-6-12 8;00-12;00 P1problem 4 完成
2021-6-12 14:00-22:00 P2 几乎完成
5 实验过程中遇到的困难与解决途径
遇到的难点 解决途径
测试优先的编程习惯非常不适应 查阅资料,逐渐习惯
Java的规约不是很熟练

查阅书籍

6 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
 设计一个完整的软件,需要从底层的ADT设计起;
 检验ADT的正确性后才能检测软件的正确性
 ADT的Spec在前期的设计非常重要,比implementation还要重要
 要认真地写spec,也包括细节的功能和注释

6.2 针对以下方面的感受
(1) 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
更加模块化
(2) 使用泛型和不使用泛型的编程,对你来说有何差异?
差异不大
(3) 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
优势是不易出错,不是很适应
(4) P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
给后续的编程带来了便利,复用降低了开发成本
(5) 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
a) 意义是提高程序的正确性和健壮性,规避错误
b) 愿意,我认为这对于测试、合作编程都很有意义
(6) 关于本实验的工作量、难度、deadline。
工作量较大,难度适中,deadline合适
(7) 《软件构造》课程进展到目前,你对该课程有何体会和建议?
感觉实验的线下课没有必要安排那么多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值