3.1.1 Get the code and prepare Git repository· 1
3.1.2 Problem 1: Test Graph <String>· 1
3.1.3 Problem 2: Implement Graph <String>· 1
3.1.3.1 Implement ConcreteEdgesGraph· 2
3.1.3.2 Implement ConcreteVerticesGraph· 2
3.1.4 Problem 3: Implement generic Graph<L>· 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.2 Implement GraphPoet· 2
3.2 Re-implement the Social Network in Lab1· 2
本次实验训练抽象数据类型(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 并据此设计测试用例。
- 实验环境配置
本次实验需要在eclipse中配置EclEmma。在eclipse市场安装即可。
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
- 实验过程
请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
在这个问题中,需要根据给定的Graph接口,分别实现边图类和点图类两个类,并且分别写他们的测试代码。在此基础之上,将String拓展为泛型L类。根据上面所完成的类,实现Poetic Walks。即若输入的两个词中间在图中有一个桥接词,则将这个词加入到输入的诗句中。
从以下地址获取初始代码:https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1
随后执行git clone将其复制到本地仓库中。
-
-
- Problem 1: Test Graph <String>
-
思路:针对Graph<String>每个方法设计等价类测试。
过程:
结果:
-
-
- Problem 2: Implement Graph <String>
-
以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
(1)AF,RI和Safety from rep exposure
(2)定义方法
为了确保内部表示不泄露,我们将字段设置为私有类型。有向图的边有起始点,终点,边的权值三个参数,分别实现即可。
注意检查表示不变性。
(3)测试策略
- 实现类ConcreteEdgesGraph
(1)AF,RI和Safety from rep exposure
(2)定义方法
(3)方法作用
Add: 向图中加入顶点,如果图中已经有待加入的顶点,则返回false
Set: 首先判断输入的两个顶点在不在图中,若不在,则调用add讲该顶点加入到图中,如果两个都在,就寻找边,若有,则返回原来的权值,并且重置权值。如果没有,则新加一条边并且返回0
Remove: 选定一个顶点,先把该顶点有关的边都删除,然后将该顶点从顶点集中移除
Vertices: 返回顶点集
sources/targets: 返回入边集,出边集
toString : 得到一个点的字符串表示
(4)测试策略
继承了Graph的测试策略,toString的测试如下:
-
-
-
- Implement ConcreteVerticesGraph
-
-
- 实现类Vertices
(1)AF,RI和Safety from rep exposure
(2)定义方法
为了确保内部表示不泄露,我们将字段设置为私有类型。有向图的点有名字,源点表,终点表三个参数,分别实现即可。
注意检查表示不变性。
(3)测试策略
- 实现类ConcreteVerticesGraph
(1)AF,RI和Safety from rep exposure
(2)定义方法
(3)方法作用
Add: 检查输入满足vertex!=null。遍历点集vertices,若已存在vertex则返回false,否则调vertices.add并返回true
Set: 遍历点集,分别检查vertices中是否存在source vertex和target vertex,若均不存在则调用vertices.add并调用source.setTarget和target.setSource设置边和权值
Remove: 除去某个点及与它相邻的所有边
vertices :返回所有的点集
sources :输入一个终点,返回与它相连的所有边和起点构成的Map
targets :输入一个起点,返回与它相连的所有边和终点构成为的Map
toString :将整个图中所有点的指向转化为一条字符串输出
(4)测试策略
继承了Graph的测试策略,toString的测试如下:
将类中的所有String类的参数替换为泛型的参数即可。
-
-
-
- Implement Graph.empty()
-
-
增添返回值即可。
增加测试。
测试通过。
-
-
- Problem 4: Poetic walks
- Test GraphPoet
- Problem 4: Poetic walks
-
测试策略:
测试结果:
-
-
-
- Implement GraphPoet
-
-
- 实现类GraphPoet
- AF,RI和Safety from rep exposure
(2)定义方法
先将其定义为一个空图,注意检查表示不变性。
(3)方法策略
此方法主要实现两个函数GraphPoet 和poem,下面分别介绍它们的实现策略。
GraphPoet:用文件输入单词,String.split()分割为数组,通过String.toLowerCase()小写化。接下来构建图,相邻的单词加边。首先要在加边前通过Graph.add()加点,加边时要判断是否存在:由于Graph.set()能返回之前加的边的值,以此来判断是否存在,存在则在之前的值加一(之前的边的值保存为lastEdgeWeight)。
poem: 输入需要进行扩充的字符串,声明一个StringBuilder保存,每次读取一个词,在garph中寻找当前词的终点表中是否有与终点词的源点表中相同的元素,并且找到权值最大的和的点加入当前点和终点之间。
测试通过!
请按照http://web.mit.edu/6.031/www/sp17/psets/ps2/#before_youre_done的说明,检查你的程序。
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
在这里给出你的项目的目录结构树状示意图。
这次实验要求我们基于Poetic Walks中定义的Graph<L>及其两种实现(本人使用的是ConcreteVerticesGraph<L>),实现Lab1中Social NetWorek中的各种功能,并且尽可能复用ConcreteVerticesGraph<L>中已经实现的方法,然后运行提供的main()和执行Lab1中的Junit测试用例,使之正常运行。
1实现类FriendshipGraph
(1)AF,RI和Safety from rep exposure
- 定义方法
设置FriendshipGraph的字段为Person构成的ConcreteEdgesGraph
(3)方法作用
Addvertex: 在图中加入顶点,并将名字加入namelist
Addedge: 根据输入的两个人名,在他们之间加一条有向边
getDistance: 返回图中两个人的最短距离
-
-
- Person类
-
-
-
- 客户端main()
- 客户端main()
-
-
-
- 测试用例
-
保持lab1测试用例不变,结果一致!
-
-
- 提交至Git仓库
-
如何通过Git提交当前版本到GitHub上你的Lab3仓库。
在这里给出你的项目的目录结构树状示意图。
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 | 时间段 | 计划任务 | 实际完成情况 |
6.1 | 18:00-22:00 | 理解所有任务 | 完成 |
6.2 | 16:00-22:30 | 完成P1边图类 | 完成 |
6.2 | 19:00-23:00 | P1点图类 | 未完成 |
6.3 | 18:00-22:30 | 完成P1点图类 | 完成 |
6.4 | 18:00-22:00 | 完成P1 设计 | 未完成 |
6.4 | 17:50-22:20 | P1设计 | 完成 |
6.5 | 19:00-22:30 | P1中点图和边图的test | 完成 |
6.6 | 20:00-22:40 | 完成P1报告 | 完成 |
6.8 | 14:00-20:30 | P1的所有测试 | 完成 |
6.9 | 13:00-21:00 | 完成P2及测试 | 完成 |
6.11 | 18:00-21:30 | 完成所有任务 | 完成 |
遇到的难点 | 解决途径 |
不理解泛型
| 通过尚硅谷的网课理解到含义 |
JAVA不熟悉导致写的速度很慢
| 再次复习网课ppt |
尽早开始做实验。
- 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
面向对象能够及时纠错,我更喜欢!
- 使用泛型和不使用泛型的编程,对你来说有何差异?
泛型使得编写的ADT更具有使用价值。
- 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
保证代码正确,不适应。
- P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
节省时间。
- 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
方便自己和他人复用代码,保证代码安全性,愿意。
- 关于本实验的工作量、难度、deadline。
合适。
- 《软件构造》课程进展到目前,你对该课程有何体会和建议?
很好。