软件构造lab2

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

Lab 2实验报告

目录

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

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实验环境配置
本次实验需要在 Eclipse IDE 中安装配置 EclEmma(一个用于统计 JUnit 测试用例的代码覆盖度的 plugin)。访问 http://www.eclemma.org,了 解 EclEmma 并学习其安装、配置和使用。经过查询了解到可以直接在eclipse中的市场中安装,在市场中搜索安装即可
在这里插入图片描述

在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/HIT-Lab2-120L021128
3实验过程
3.1Poetic Walks
主要目的是练习ADT的规约设计和ADT的实现。
3.1.1Get the code and prepare Git repository
得到网址。
https://github.com/rainywang/Spring2022_HITCS_SC_Lab2/tree/master/P1
然后在GITbash直接执行
git clone https://github.com/rainywang/Spring2022_HITCS_SC_Lab2.git下载工程文件
然后打开自己本次实验github的网址,在D盘中执行
Git clone https://github.com/ComputerScienceHIT/HIT-Lab2-120L021128.git
在这里插入图片描述

3.1.2Problem 1: Test Graph
这部分主要是针对Graph设计相应的测试策略,主要利用等价划分的思想进行测试。
在这里插入图片描述
在这里插入图片描述

3.1.3Problem 2: Implement Graph
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
3.1.3.1Implement ConcreteEdgesGraph
3.1.3.1.1实现EDGE类
(1)定义两个私有String类型source和target存放每个边的起止点,定义一个私有int类型weight保存这条边的权值。
在这里插入图片描述

(2)方法如下
Edge 构造方法,初始化新边的两个点和边的权值
getsource 返回边的一个点source
gettarget 返回边的另外点target
getweight 返回边的权值weight
toString 返回一个字符串表明这条边从哪个source到哪个target,weight是多少
checkRep 检查表示不变性,其中source和target必须非空,weight必须大于0
(3)AF,RI和Safety from rep exposure如下图
在这里插入图片描述

(4)测试策略
在这里插入图片描述

3.1.3.1.2 实现ConcreteEdgesGraph类:
(1)定义私有的顶点表和边表:
在这里插入图片描述

(2)在ConcreteEdgesGraph中需要实现的方法如下图所示:
ConcreteEdgesGraph 构造方法
add 如果顶点不为空,添加一个顶点
checkRep 检查表示不变量,其中source和target必须为空,weight必须大于0
set 输入source,target,weight,确定一条有向边。
若weight<0,返回-1;
若weight>0且新边已经存在,则删去原边,添加新边;若新边不存在,直接加入新的边
若weight=0,寻找可能已经存在的相同的边,删去。
remove 除去某个点及与它相邻的所有边。遍历edges,寻找是否有边的起点或者终点是该点,删去。
verticies 返回所有的vertices集合。
sources 输入一个终点,返回与它相连的所有边和起点构成的map
targets 输入一个起点,返回与它相连的所有边和起点构成的map
toString 对每条边调用toString方法,整合起来
(3)AF,RI和Safety from rep reposure如下图:
在这里插入图片描述

(4)测试策略
在这里插入图片描述

测试结果:
在这里插入图片描述

检查覆盖率:
在这里插入图片描述

3.1.3.2Implement ConcreteVerticesGraph
3.1.3.2.1 Vertex类:

(1)定义私有类型,包括点的名字,点的起点表,点的终点表:
在这里插入图片描述

(2)实现方法如下图:
Vertex 构造方法,传入name创建新的点
checkRep 检查表示不变性,每个边的权值应该大于0
getname 返回点的名字name
getsource 返回以某点为终点的所有点和边构成的Map
gettarget 返回以某点为起点的所有点和边构成的Map
removesource 删去某起点
removetarget 删去某终点
toString 得到一个点的字符串表示
setsource 新增一个起点source
若weight为0,删去当前点的source,不存在返回0;
若weight>0,将其加入source中,若该点已存在则更新其weight并返回原weight,不存在则直接构建新点并返回0.
若weight<0返回-1
settarget 新增一个终点target
若weight为0,删去当前点的target,不存在返回0;
若weight>0,将其加入target中,若该点已存在则更新其weight并返回原weight,不存在则直接构建新点并返回0.
若weight<0返回-1
(3)AF,RI和Safety from rep reposure:
在这里插入图片描述

(4)测试策略

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试结果:
在这里插入图片描述

检查覆盖率:
在这里插入图片描述

3.1.4Problem 3: Implement generic Graph
3.1.4.1Make the implementations generic
使用泛型实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

充分利用eclipse的改错功能快速修改成泛型实现。
3.1.4.2Implement Graph.empty()
调用一个具体实现:
在这里插入图片描述

整体测试并检查覆盖率:

在这里插入图片描述
在这里插入图片描述

3.1.5Problem 4: Poetic walks
利用之前实现的图结构,完成利用已经存在的诗句对一个新的句子进行扩充的任务。
3.1.5.1Test GraphPoet

测试策略:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

测试结果:
在这里插入图片描述

测试覆盖率:
在这里插入图片描述

3.1.5.2Implement GraphPoet

(1)定义私有类型的表如下图所示:
在这里插入图片描述

(2)AF,RI和Saftey from rep reposure如下图
在这里插入图片描述

(3)实现方法如下
GraphPoet 输入文件的路径,一行一行读入,存储在List中,然后每次读取相邻元素,在图中新增边
poem 输入需要进行扩充的字符串,声明一个StringBuilder保存返回结果。每次读取一个词,然后以当前词为source,下一个词为target,在graph中寻找符合此条件的边,记录权值,结束后选择权值最大的,利用StringBuilder. Append方法,将节点名字加入字符串。在这里插入图片描述

toString 调用ConcreteEdgesGraph中的toString方法,将整个图中所有点的指向转化为一条字符串输出
checkRep 检查不变性。

3.1.5.3Graph poetry slam
Main 函数:
在这里插入图片描述

输入数据为Test the system.
文本数据为:
在这里插入图片描述

输出为:
在这里插入图片描述

3.1.6Before you’re done
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在工作目录下打开Git Gui
依次点击依次点击:rescan,stage change,输入commit信息,commut,push,就完成了。
在这里插入图片描述

在这里给出你的项目的目录结构树状示意图。
在这里插入图片描述

3.2Re-implement the Social Network in Lab1
利用之前实现的graph,重新实现Social Network。
3.2.1FriendshipGraph类

(1)定义私有类型如下图所示:
在这里插入图片描述

(2)实现方法如下图所示
FriendshipGraph 构造方法
addVertex 增加新的点,调用ConcreteEdgesGraph中的add即可:
在这里插入图片描述

addEdge 增加a的新朋友b,直接调用ConcreteEdgesGraph中的set即可:
在这里插入图片描述

getpeople 在这里插入图片描述

getDistance 得到两人之间的最短距离。使用队列和深度优先搜索。
流程为:入队,循环(出队,将朋友全部入队,检查是否是P2,不是就加入distantMap,设置距离,是就返回)
在这里插入图片描述

3.2.2Person类
(1)Person类相比之前的邻接表可以大幅缩减
声明name保存名字,和一个personlist表用来避免声明重复的人
在这里插入图片描述

(2)实现方法:
Person 没有重复就加入,构造方法
GetName 返回名字

3.2.3客户端main()
可使用LAB1中的main
在这里插入图片描述

运行后结果为:
在这里插入图片描述

3.2.4测试用例
与LAB1的测试方法相同:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试结果为:
在这里插入图片描述

检测覆盖率(注释掉main):
在这里插入图片描述

3.2.5提交至Git仓库
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在工作目录下打开Git Gui
依次点击:rescan,stage change,输入commit信息,commut,push,就完成了。
在这里插入图片描述

在这里给出你的项目的目录结构树状示意图。
在这里插入图片描述

4实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 计划任务 实际完成情况
5.17 18:00-23:00 P1中的GraphInstanceTest 未完成
5.18 13:00-15:00 P1中的GraphInstanceTest 按时完成
5.19 18:00-23:00 P1中的ConcreteEdgesGraph 按时完成
5.20 14:00-18:00 P1中的ConcreteEdgesGraphTest 未按时完成
5.22 15:00-17:00
19:00-23:00 P1中的ConcreteVerticesGraph并写注释 按时完成
5.23 17:00-23:00 完成Problem3 按时完成
5.24 18:00-22:00 完成P1 按时完成
5.25 13:00-17:00
18:00-23:00 完成P2及测试 按时完成
5实验过程中遇到的困难与解决途径
遇到的难点 解决途径
P1是全英文题目,刚开始没看懂要干什么

经过与同学之间的探讨和不断的理解,最终明白了应该怎么做

不理解什么是泛型

通过查资料最终得知

6实验过程中收获的经验、教训、感想
6.1实验过程中收获的经验和教训
通过自行设计多种类才实现功能,感觉让他们互相配合的能力很差,关系很复杂,代码很繁乱。对于java还是不熟练,需要提高。
6.2针对以下方面的感受
(1)面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
对实际物体进行抽象,与面向过程的编程思路完全不同。
(2)使用泛型和不使用泛型的编程,对你来说有何差异?
泛型更加灵活。
(3)在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
可以提高代码的正确性且能及时进行修改,不是很适合,习惯了先写代码。
(4)P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
T
提高代码的利用率,使代码精简
(5)为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
防止内部变量被外部修改。我愿意
(6)关于本实验的工作量、难度、deadline。
工作量大,难度适中,deadline之前有两门考试,相对紧张
(7)《软件构造》课程进展到目前,你对该课程有何体会和建议?
希望可以不全部照搬MIT的实验,或者对其加上一些注释和修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值