软件构造实验二(完整)

目录

1 实验目标概述

2 实验环境配置

3 实验过程

3.1 Poetic Walks

3.1.1 Get the code and prepare Git repository

3.1.2 Problem 1: Test Graph <String>

3.1.3 Problem 2: Implement Graph <String>

3.1.3.1 Implement ConcreteEdgesGraph

3.1.3.2 Implement ConcreteVerticesGraph

3.1.4 Problem 3: Implement generic Graph<L>

3.1.4.1 Make the implementations generic

3.1.4.2 Implement Graph.empty()

3.1.5 Problem 4: Poetic walks

3.1.5.1 Test GraphPoet

3.1.5.2 Implement GraphPoet

3.1.5.3 Graph poetry slam

3.1.6 Before you’re done

3.2 Re-implement the Social Network in Lab1

3.2.1 FriendshipGraph

3.2.2 Person

3.2.3 客户端main()

3.2.4 测试用例

3.2.5 提交至Git仓库

4 实验进度记录

5 实验过程中遇到的困难与解决途径

6 实验过程中收获的经验、教训、感想

6.1 实验过程中收获的经验和教训

6.2 针对以下方面的感受

  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 并据此设计测试用例。

  1. 实验环境配置

实验环境配置:大体上与Lab1相同,包括JDK11与Junit4,除此之外我还需要在IDEA中配置Code Coverage for Java,用来检查我们测试的覆盖率,社区版(我使用的是社区版)IDAE自带Code Coverage for Java插件,只能选择使用或者禁用,不能卸载,如图

 

  1. 实验过程

请仔细对照实验手册,针对两个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

    1. Poetic Walks

这个任务的目的是完善并使用一个图的模块,需要我们完善Graph接口类,实现Graph类中的方法,包括:add,set,remove,vertices,sources,targets,最后实现GraphPoet类。最后这个类是从输入的文本的两个单词之间如果存在桥接词,就将该桥接词插入,如果有多个则选取权重较大的(如果有多个并列,则随机)。

      1. Get the code and prepare Git repository

在Git Bash中使用命令git clone + URL地址,从老师那里克隆代码

Git clone https://classroom.github.com/a/NL2TjK2z

      1. Problem 1: Test Graph <String>

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。

思路:这是针对Graph<String>设计相应的测试策略,主要针对里面的每个方法进行等价类划分的测试。

过程:如图:

 

 

 

 

结果:

 

 

我将所有的方法测试放入到一个覆盖率报告中,所以没有了单个方法的覆盖率,下同,我生成了一个覆盖率的报告文档,是一个html文件,在目录test\P1\graph下,是对这个包中所有方法的测试报告,文件名为index.heml,从报告中可以看出在我这个包中的类的覆盖率达到了百分之80,方法覆盖百分之97.4,行覆盖百分之98.6,总体上看覆盖率比较高。

      1. Problem 2: Implement Graph <String>

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。

        1. Implement ConcreteEdgesGraph
  1. 实现Edge类:
  1. Edge中应该包括边的权重,边的起始顶点和目标顶点,防止内存泄漏,所以将其设置为private

 

  1. Edge中所实现的方法为:

Edge类

初始化边的起始顶点和目标顶点以及权重

checkRep

检查表示不变性:边的权重大于等于0

getsource

返回一个起始顶点

gettarget

返回一个目标顶点

getweight

返回边的权重

toString

返回一条边的字符串:“起始顶点->目标顶点权重为xx”

  1. AF,RI和防止内存泄漏

 

  1. 测试方法:

 

  1. 实现ConcreteEdgesGraph类
  1. 这个类中包括边表list和顶点表set

 

  1. 实现的方法有:

ConcreteEdgesGraph

checkRep

检查表示不变性:边的长度为大于0的数且有起始顶点

add

添加一个顶点到顶点集合中

set

参数为source,target,weight,边存在且权重为正,则返回原来的权重;边不存在且权重为正,则返回0;权重为负数,则返回-1

remove

删除一个顶点和与之相关的边,遍历Edges,运用迭代器寻找是否以这个点为起始顶点或者目标顶点

vertices

返回所有顶点的集合

sources

输入一个目标顶点,返回和他相连的所有的边和起始顶点构成的集合

targets

输入一个起始顶点,返回和他相连的所有的边和目标顶点构成的集合

toString

将图中所有的点转化为一条可以输出的字符串

  1. AF,RI,防止内存泄漏:

 

  1. 测试方法:

对toString进行测试,其余直接继承Graph测试:

 

测试结果:

 

 

我生成了一个覆盖率的报告文档,是一个html文件,在目录test\P1\graph下,是对这个包中所有方法的测试报告,文件名为index.heml,从报告中可以看出在我这个包中的类的覆盖率达到了百分之80,方法覆盖百分之97.4,行覆盖百分之98.6,总体上看覆盖率比较高。

        1. Implement ConcreteVerticesGraph
  1. Vertex类
  1. 这个类包含顶点的名字,起始顶点的集合以及目标顶点的集合

 

  1. 实现的方法:

Vertex

用顶点的名字创建顶点表

checkRep

检查表示不变性:边的权重大于0

getmark

返回顶点的名字

getsource

返回能到达这个顶点的所有的点和边的集合

gettarget

返回这个顶点能到达的所有顶点和边的集合

addsource

在起始顶点集合中加入一个起始顶点,如果权重大于0且顶点已经存在,则返回原来的权重;如果权重大于0且顶点不存在,则返回0;如果权重等于0,则移除这个顶点

addtarget

在目标顶点集合中加入一个目标顶点,如果权重大于0且顶点已经存在,则返回原来的权重;如果权重大于0且顶点不存在,则返回0;如果权重等于,则移除这个顶点

removesource

在起始顶点集合中删除一个起始顶点,并且返回原来的权重

removetarget

在目标顶点集合中删除一个目标顶点,并且返回原来的权重

toString

得到一个顶点的字符串表示

  1. AF,RI和防止内存泄漏

 

  1. 测试方法:

 

 

 

 

 

 

 

  1. ConcreteVerticesGraph类
  1. 顶点构成的集合

 

  1. 实现的方法:

ConcreteVerticesGraph

checkRep

检查表示不变性:顶点集合中不应该有重复的顶点

add

添加一个顶点到顶点集合中

set

参数source,target,weight,如果边存在且权重大于0,则返回原来的权重;如果边不存在且权重大于0,则返回0;如果权重为负数,则返回-1

remove

删除一个顶点和与之相关的边,使用迭代器遍历Vertex在起始顶点集合和目标顶点集合中寻找是否有重复的顶点

vertices

所有顶点的集合

sources

输入一个起始顶点,返回与他相连的所有边和起始顶点构成的集合

targets

输入一个目标顶点,返回与他相连的所有边和目标顶点构成的集合

toString

将图转换成一条可以输出的字符串

  1. AF,RI和防止内存泄露

  1. 测试方法:

对toString进行测试,继承Graph的测试:

 

      1. Problem 3: Implement generic Graph<L>
        1. Make the implementations generic

将String改为泛型实现

 

 

 

 

        1. Implement Graph.empty()

具体实现:

 

测试方法:

 

测试结果:

 

 

我生成了一个覆盖率的报告文档,是一个html文件,在目录test\P1\graph下,是对这个包中所有方法的测试报告,文件名为index.heml,从报告中可以看出在我这个包中的类的覆盖率达到了百分之80,方法覆盖百分之97.4,行覆盖百分之98.6,总体上看覆盖率比较高。

      1. Problem 4: Poetic walks

任务要求我们实现一个类,利用之前实现的图结构,能够将语料库转化为该种图结构,并且在图中搜索,完成对输入的诗句的句子进行扩充。

        1. Test GraphPoet

测试方法:

 

 

 

具体实现:

 

 

 

测试结果:

 

 

我生成了一个覆盖率的报告文档,是一个html文件,在目录test\P1\graph下,是对这个包中所有方法的测试报告,文件名为index.heml,从报告中可以看出在我这个包中的类的覆盖率达到了百分之80,方法覆盖百分之97.4,行覆盖百分之98.6,总体上看覆盖率比较高。

        1. Implement GraphPoet
  1. 用String构成Graph

 

  1. 实现方法:

GraphPoet

按行读入文件,放在list中,每次取出相邻的元素,在图中加入新的边

checkRep

检查表示不变性

poem

输入需要扩充的字符串,当前单词为source,下一个单词为target,找其中权重最大的加入其之间

 

toString

调用ConcreteEdgesGraph中toString方法,转化成字符串输出

        1. Graph poetry slam

利用toString进行输出:

 

main函数中运行结果:

 

 

      1. Before you’re done

请按照http://web.mit.edu/6.031/www/sp17/psets/ps2/#before_youre_done的说明,检查你的程序。

如何通过Git提交当前版本到GitHub上你的Lab2仓库。

 

之前传上去忘记截图了

 

在这里给出你的项目的目录结构树状示意图。

 

我后来添加了覆盖率的生成报告,所以这里的截图缺少了index.html文件,但是我会将Index.html文件一并传到gitHub上去

    1. Re-implement the Social Network in Lab1

这次实验要求我们基于Poetic Walks中定义的Graph<L>及其两种实现(在这里我所使用的是ConcreteEdgesGraph<L>),实现Lab1中Social NetWorek中的各种功能,并且尽可能复用ConcreteEdgesGraph<L>中已经实现的方法,然后运行提供的main()和执行Lab1中的Junit测试用例,使之正常运行。

      1. FriendshipGraph

(1)将FriendshipGraph中的ConcreteEdgesGraph的L改为Person,并设置为私有

 

(2)FriendshipGraph中所实现的方法有:

FriendshipGraph

addVertex

在一个图中增加新的人,需要调用ConcreteEdgesGraph中的add

 

addEdge

为一个人增加一个新的朋友,a表示某个人,b表示他的朋友,需要调用ConcreteEdgesGraph中的set

 

getallPeople

直接将这个图返回

 

getDistance

得到两个人之间的最短距离,定义一个Person队列myqueue用来存储先广搜索的遍历结果,定义一个Map集合route用来存储先广搜索的所有元素与第一个元素之间的距离。首先将a入队,并且把a和第一个下标0放入集合,当队列非空时弹出队首元素top,并且得到top在route中的下标distance,定义一个Map为friend,执行personGraph.targets(top)得到队首元素的所有朋友的集合,定义一个Set为allfriend,对friend执行KeySet得到allfriend,只要allfriend中的元素与b不同,就将这些元素全部入队,并且把这些元素极其下标distance+1放入到集合中,只要队列非空,循环执行上述步骤,知道找到某个元素与b相同,并且返回这个元素在route中的下标,如果队列为空还未找到,则返回-1

 

main

实现Lab1中实验指导的客户端

 

  1. AF,RI和防止表示泄露:

 

      1. Person
  1. 定义一个私有类型的myname和allperson

 

  1. Person中所实现的方法:

Person

构造方法

Person

将没有重复的名字加入

getmyname

返回这个人的名字

  1. AF,RI和防止表示泄露:

 

      1. 客户端main()

按照实验一中的实验指导所阐述的社交网络图构建一个客户端

 

      1. 测试用例

测试策略:与实验一中进行的测试相同

 

 

 

 

测试结果:

 

 

从测试结果来看覆盖率比较高

      1. 提交至Git仓库

如何通过Git提交当前版本到GitHub上你的Lab2仓库。

 

 

 

 

 

在这里给出你的项目的目录结构树状示意图。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒不是我的fault

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值