软件构造lab2 - 实验报告

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.环境配置

简延续Lab1中的实验环境,除此之外,本次实验在 Eclipse IDE中安装配置 EclEmma(一个用于统计JUnit测试用例的代码覆盖度测试用例的代码覆盖度plugin)
https://github.com/ComputerScienceHIT/Lab2-1180300119

3.实验过程

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

3.1Poetic Walks

1.对给定的接口Graph,完成他的两个实例类ConcretVerticesGraph和ConcreateEgdesGraph:
(1)首先分别构造两个实例类的rep类Vertex和Edge;
(2)用String作为L的特例,分别在两个实例类中实现Graph接口中的各个方法,写对应的test文件以确保其正确性;
(3)将所有String变量替换为泛型L。
2. 对给定的文本文件,按照给定规则建立有向图,调用Graph作为存储语料库的数据结构,利用该结构,对输入的字符串进行扩充。

3.1.1Get the code and prepare Git repository

请阅读 http://web.mit.edu/6.031/www/sp17/psets/ps2/,遵循该页面内的要求完
成编程任务。
⚫ 在 Get the code 步骤中,你无法连接 MIT 的 Athena 服务器,请从以下地址获取初始代码:
https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1
⚫ 在作业描述中若遇到“commit and push”的要求,请将你的代码 push 到你的 GitHub Lab2 仓库中。
⚫ MIT 作业页面提及的文件路径,请按照下表的目录结构进行调整。例如
“test/poet”应为“test/P1/poet”,
“src/poet”应为“src/P1/poet”。
⚫ 其他步骤请遵循 MIT 作业页面的要求。
https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1获得实验代码。

3.1.2Problem 1: Test Graph

以静态 Graph.empty()方法的测试策略和测试都在GraphStaticTest.java,为了运行这个测试,首先要修改Graph empty()为:
public static String Graph empty() {
Graph graph = new ConcreteEdgesGraph();
return graph;
}
这里以ConcreteEdgesGraph作为Graph默认的实例类。

3.1.3Problem 2: Implement Graph

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。
GraphInstanceTest
// Testing strategy
// 此test与具体实现无关
//
// 测试Graph.add()方法:
// 如果未存在该顶点,修改graph,加入顶点集,返回True
// 否则图不变,返回False
//
// 测试Graph.remove()方法:
// 如果不存在该点,图不变,返回False
// 否则删除该点,并删除相邻的边,返回True
//
// 测试Graph.sources()方法
// graph为空
// set点和边,创建一个map进行同步操作
// 与map比较 , 对应关系是否正确
//
// 测试Graph.targets()方法
// graph为空
// set点和边,创建一个map进行同步操作
// 与map比较 , 对应关系是否正确
//
// 测试Graph.set()方法:
// 分开测试weight的情况 : 0 , > 0
// weight为0检查边是否被删除
// weight > 0 , 检查边是否被添加或更新
// 比较输出tostring
//
// 测试Graph.vertices()方法:
// graph为空
// graph添加顶点后,删除定点
// 观察顶点的数量
//
//测试All:
//graph为空
//graph进行所有操作
//与期望比较

3.1.3.1Implement ConcreteEdgesGraph

一.补全ConcreteEdgesGraph部分:
// Abstraction function:
// 通过对graph中边和点的抽象
// 边的类中包含了source,target,weight
// 带方向的边
// 构成有向图
// Representation invariant:
// 不变量在于隐含的数学关系
// n个点,最多构成n*(n-1)/2条有向边
// Safety from rep exposure:
// 在可操作的情况下,所有的变量都定义为private , final
// 防御式拷贝
// 使用Collections.unmodifiableSet等方法
构造函数:
public ConcreteEdgesGraph() {
}

private void checkRep():每个function返回前检查rep不变
@Override public boolean add(L vertex)
如果在vertices的Set集合中成功添加了顶点string,则返回true,如果重复,返回false。
private int FindEdge(L source, L target)
为了找到edges里是否存在一条指定的边,该边的source和target必须与传入的参数相等,返回该边的index
@Override public int set(L source, L target, int weight)
根据source和target调用findEdge()返回指定边的index。当weight>0,如果index<0,没找到指定边,则添加顶点和边;如果index>0并且找到了指定边,则update这条边。当weight>0且index<0时,找到了指定边,将其删除/最后checkRep()。
@Override public boolean remove(L vertex)
如果不含删除点,返回false。否则遍历edges,如果某个edge的source或是target与vertex相等,则删除该边。最后删除vertex点。并checkRep。

@Override public Set vertices()
{
return Collections.unmodifiableSet(vertices);
}
返回Set vertices,使用Collections.unmodifiableSet()方法保证safety from rep exposure。

@Override public Map<L, Integer> sources(L target)
建立一个map,遍历edges,如果某个edge的edge.getTarget()和传入参数target相等,则将该边的source和weight存入map中。

@Override public Map<L, Integer> targets(L source)
建立一个map,遍历edges,如果某个edge的edge.getSource()和传入参数source相等,则将该边的target和weight存入map中。

public String toString()
graph空,则返回“This is An Empty Graph”.graph不为空,则将每个边的toString连接起来

二.实现class Edge部分:
private final Set vertices = new HashSet();
private final List<Edge> edges = new ArrayList<Edge>();
// Abstraction function:
// 通过对graph中边和点的抽象
// 边的类中包含了source,target,weight
// 带方向的边
// 构成有向图
// Representation invariant:
// 不变量在于隐含的数学关系
// n个点,最多构成n*(n-1)/2条有向边
// Safety from rep exposure:
// 在可操作的情况下,所有的变量都定义为private , final
// 防御式拷贝
// 使用Collections.unmodifiableSet等方法
构造函数:
public Edge(L source,L target,int w){
this.weight=w;
this.sourceVertex=source;
this.targetVertex=target;
checkRep();
}
public void checkRep() {
assert sourceVertex != null;
assert targetVertex != null;
assert weight>=0;
}
各个field的getter
public L getSource() {
return sourceVertex;
}

public L getTarget() {
	return targetVertex;
}

public int getWeight() {
	return weight;
}

@Override public String toString()
{
String s = this.getSource() + “->” + this.getTarget() + “:” +this.getWeight();
return s;
}
输出形式:V1->V2:weight
ConcreteEdgesGraphTest
// Testing strategy
//
// 测试ConcreteEdgesGraph().tostring()方法:
// 随意创建一个图
// 用tostring与预期输出比较
//
// 测试Edges:
// 随意创建一条边
// 用tostring与预期输出比较

3.1.3.2Implement ConcreteVerticesGraph

一.ConcreteVerticesGraph部分:
// Abstraction function:
// 将有向加权图描述为多个顶点
// 点之间的映射关系为边
// 边有权值weight
//
// Representation invariant:
// 每个顶点只能存在一个实例
//
// Safety from rep e

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值