目录
3.2 Re-implement the Social Network in Lab1
1.实验目标概述
本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象
编程(OOP)技术实现 ADT。具体来说:
l 针对给定的应用问题,从问题描述中识别所需的 ADT;
l 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
l 根据 ADT 的规约设计测试用例;
l ADT 的泛型化;
l 根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示
(representation)、表示不变性(rep invariant)、抽象过程(abstraction
function)
l 使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表
示泄露(rep exposure);
l 测试 ADT 的实现并评估测试的覆盖度;
l 使用 ADT 及其实现,为应用问题开发程序;
l 在测试代码中,能够写出 testing strategy 并据此设计测试用例。
2.实验环境配置
构建git仓库
在GitHub Classroom中按照提示建立自己的 Lab2 仓库并关联至自己的学号。
代码覆盖率工具
IDEA自带代码覆盖率工具,只需右键单击测试文件,选择Run with Coverage即可:
3.实验过程
请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1Poetic Walks
该任务主要是实验一个图的模块,并基于此使用。
(1)完善Graph接口类,并运用泛型的思想,将String拓展为泛型L类;
(2)实现Graph类的方法:add、set、remove、vertices、sources、targets;
(3)利用实现的Graph类,应用图的思想,实现GraphPoet类,如果输入的文本的两个单词之间存在桥接词,则插入该桥接词;若存在多个单一桥接词,则选取边权重较大者。
3.1.1 Get the code and prepare Git repository
进入https://github.com/rainywang/Spring2022_HITCS_SC_Lab2/tree/master/P1
获取代码地址
将代码clone到本地
将Spring2022_HITCS_SC_Lab2中P1代码复制到HIT-Lab2-2021112324中并在IDEA中修改项目的目录结构
3.1.2 Problem 1: Test Graph <String>
这部分主要是针对Graph设计测试策略,编写测试用例主要利用等价类划分的思想进行测试,测试策略如下:
编写覆盖以上条件的测试用例
3.1.3 Problem 2: Implement Graph <String>
3.1.3.1 Implement ConcreteEdgesGraph
1. 实现Edge
Filed:
Filed | 作用 |
private final String source | 初始节点 |
private final String target | 目标节点 |
private final String weight | 有向边的权值 |
AF、RI、Safety:
checkRep:
初始节点、目标节点不为空;
初始节点!=目标节点;
边的权值>=0
Method:
Method | 作用 |
public String getSource() | 返回起始节点 |
public String getTarget() | 返回目标节点 |
public int getWeight() | 返回有向边权值 |
public String toString() | 输出边的信息 |
2. 实现ConcreteEdgeGraph
Filed:
Filed | 作用 |
private final Set<String> vertices | 点集 |
Private final List<Edge> edges | 边集 |
AF、RI、Safety:
checkRep():
边集中任意边的权值>=0;
边集中任意边的任意节点都在点集中;
边集中任意边的两个节点不相同;
Method:
Method | 作用 |
public boolean add(String vertex) | 向点集添加vertex点 |
public int set(String source,String target,int weight) | 修改边集内的边(若边的节点不在点集内,则把点加入点集),若边集内存在相同边,则对已有边做修改,并返回已有边的权值;若边集内不存在相同边,则添加该边,并返回0 |
public boolean remove(String vertex) | 删除点集内的vertex点 |
public Set<String> vertices | 返回点集 |
public Map<String,Integer> sources(String target) | 生成并返回以target点为目标节点的所有有向边的初始节点集 |
public Map<String,Integer> targets(String source) | 生成并返回以source点为初始节点的所有有向边的目标节点集 |
public String toString() | 输出图的所有点及其相关边的信息 |
3. 测试结果
3.1.3.2 Implement ConcreteVerticesGraph
1. 实现Vertex
Filed:
Filed | 作用 |
private final Map<String,Integer> sources | 以该点为目标节点的所有边的初始节点集 |
private final Map<String,Integer> targets | 以该点为初始节点的所有边的目标节点集 |
private final String name | 该点名称 |
AF、RI、Safety:
checkRep():
点的名字不为null;
该点储存的sources和targets两个图中都不含与该点相同的点;
Method:
Method | 作用 |
public String getName() | 返回点的名字 |
public Map<String,Integer> getSources() | 返回以该点为目标节点的所有边的初始节点集 |
public Map<String,Integer> getTargets() | 返回以该点为初始节点的所有边的目标节点集 |
public void addSource(String source,Integer weight) | 向以该点为目标节点的所有边的初始节点集中加入新初始节点 |
Public void addTarget(String target,Integer weight) | 向以该点为初始节点的所有边的目标节点集中加入新目标节点 |
public String toString | 输出与该节点相关的初始节点集合目标节点集的相关信息 |
2. 实现ConcreteEdgesGraph
Filed:
Filed | 作用 |
private final List<Vertex> vertices | Vertex类点集 |
AF、RI、Safety:
checkRep:
点集中任意两点都不同
Method:
Method | 作用 |
public boolean add(String vertex) | 向点集添加vertex点 |
public int set(String source,String target,int weight) | 修改边集内的边(若边的节点不在点集内,则把点加入点集),若边集内存在相同边,则对已有边做修改,并返回已有边的权值;若边集内不存在相同边,则添加该边,并返回0 |
public boolean remove(String vertex) | 删除点集内的vertex点 |
public Set<String> vertices | 返回点集 |
public Map<String,Integer> sources(String target) | 生成并返回以target点为目标节点的所有有向边的初始节点集 |
public Map<String,Integer> targets(String source) | 生成并返回以source点为初始节点的所有有向边的目标节点集 |
public String toString() | 输出图的所有点及其相关边的信息 |
3. 测试结果
3.1.4 Problem 3: Implement generic Graph<L>
3.1.4.1 Make the implementations generic
ConcreteEdgeGraph和ConcreteEdgesGraph两个实例类中的所有String类的参数替换为泛型的参数L即可(声明、函数参数、返回值、rep)
3.1.4.2 Implement Graph.empty()
修改Graph.empty为:
ConcreteVerticesGraph作为Graph默认的实例类,也可以用ConcreteEdgesGraph,二者是等价的。
测试结果:
3.1.5 Problem 4: Poetic walks
该任务要求利用之前已经实现的图的结构,实现一个能够将语料库转化为图的一个类,并实现在图中的搜索以及对输入的诗句进行扩充的功能。
3.1.5.1 Test GraphPoet
测试策略:
3.1.5.2 Implement GraphPoet
Filed
Filed | 作用 |
private final Graph<String> graph | 文件中单词所构成的图 |
AF、RI、Safety:
checkRep:
图不为null
Method:
Method | 作用 |
public GraphPoet(File corpus) | 打开文件,读取文件输入,识别序列,构建图结构,将语料库转化为图的一个类 |
public String poem(String input) | 实现在图中的搜索以及对输入的诗句进行扩充的功能 |
public String toString() | 输出图的信息 |
测试结果:
3.1.5.3 Graph poetry slam
根据以提供的代码,修改相对路径,输出字符串即可。
3.1.6 使用Eclemma检查测试的代码覆盖度
IDEA自带检查测试代码覆盖度的工具,用该工具测得的各测试用例的代码覆盖度如下:
ConcreteEdgesGraphTest:
ConcreteVerticesGraphTest:
GraphStaticTest:
GraphInstanceTest:
GraphPoetTest:
3.1.7 Before you’re done
请按照http://web.mit.edu/6.031/www/sp17/psets/ps2/#before_youre_done的说明,检查你的程序。
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
git add .
git commit -m “xxx”
git push
在这里给出你的项目的目录结构树状示意图。
3.2 Re-implement the Social Network in Lab1
用在Poetic Walks已经实现的Graph<L>来实现Lab1中的FriendshipGraph类的各个方法,使之能通过测试文件,并且运行main函数的结果与Lab1一致。概述你对该任务的理解。
3.2.1 FriendshipGraph类
Filed:
Filed | 作用 |
private final ConcreteEdgesGraph<Person> personGraph | 人际关系图 |
AF、RI、Safety:
Method:
Method | 作用 |
public void addVertex(Person person) | 向人际关系图中加入一个人(点) |
public void addEdge(Person person) | 向人际关系图中加入一个(单向)朋友关系(有向边) |
Public int getDistance(Person person1,Person person2) | 计算两个人之间的社交距离(两个人之间需要多少个朋友关系才能构建联系) |
3.2.2 Person类
Filed | 作用 |
private final String name | 人的名字 |
AF、RI、Safety:
checkRep:
名字不为空
Method:
Method | 作用 |
public String getName() | 返回这个人的名字 |
3.2.3 客户端main()
Main()函数内容可以沿用实验1中的内容,其效果相同:
3.2.4 测试用例
先分别给FriendshipGraph中的方法测试,然后测试简单图和复杂图
方法测试:
简单图:
复杂图:
3.2.5提交至Git仓库
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
git add .
git commit -m “xxx”
git push
在这里给出你的项目的目录结构树状示意图。