【无标题】

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

Lab 2实验报告

姓名 刁浩宇
学号 120L020120
班号 2003010
电子邮件 120L020120@stu.hit.edu.cn
手机号码 13231750698

目录

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

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 实验环境配置
在这里插入图片描述
https://github.com/ComputerScienceHIT/HIT-Lab2-Smallwhispe.git
2 实验过程
2.1 Poetic Walks
在这里简要概述你对该任务的理解。
2.1.1 Get the code and prepare Git repository
如何从GitHub获取该任务的代码、在本地创建git仓库、使用git管理本地开发。
2.1.2 Problem 1: Test Graph
Empty是一个静态工厂,在具体实现时候,要将L改成String
在这里插入图片描述
Graph Static Test中需要暂时实现Vertices,返回空集即可,此时运行Graph Static Test即可得到测试结果:
在这里插入图片描述
接下来实现Graph Instance Test.java
在这个测试文件中,我们对于边和顶点的测试应该是通用的,此test与具体实现无关,所以依次测试各个方法 以string测试
在这里插入图片描述
//测试add函数
在这里插入图片描述
//测试set函数
在这里插入图片描述
在这里插入图片描述
//测试remove函数
在这里插入图片描述
//测试vertices函数
在这里插入图片描述
//测试sources函数
在这里插入图片描述
//测试targets函数
在这里插入图片描述
//测试覆盖度可以达到97%
在这里插入图片描述
2.1.3 Problem 2: Implement Graph
2.1.3.1 Implement ConcreteEdgesGraph

// Abstraction function:
// TODO
// Vertices sets are abstracted into points,
// Edges are abstracted into edges, which make up graphs
// Representation invariant:
// TODO
// n points have at most n(n-1) edges
// Safety from rep exposure:
// TODO
// All parameters are private and a get method is added
// Use defensive copies when necessary
在这里插入图片描述
在这里插入图片描述
如果之前没有该点并且成功加入该点,返回true
在这里插入图片描述
遍历各边如果target和source都相等则看weight是否相等如果不等于零则更新weight,并返回之前的weight
如果没有找到相同的target和source对,就看weight是否为零然后加入该新边
在这里插入图片描述
如果不含该点,返回false。否则遍历edges,如果某个edge的source或是target与vertex与该顶点相连,则删除该边。最后删除vertex和所有edge。并checkRep。
在这里插入图片描述
返回vertices的Set,注意做到使用了防御式拷贝
在这里插入图片描述
建立一个map,遍历edges,如果egdes是空的则返回空的map,如果某个edge的edge.getTarget()和传入参数target相等,则将该边的source和weight存入map中。
在这里插入图片描述
建立一个map,遍历edges,如果egdes是空的,则返回空的map,如果某个edge的edge.getSource()和传入参数source相等,则将该边的target和weight存入map中。
在这里插入图片描述

// rep
private final L source,target;//源顶点和目标顶点
private final int weight;//权值
// Abstraction function:
// TODO
// Abstracts a triplet (source, weight, target) into a directed edge
// Representation invariant:
// TODO
// Neither source nor target is null, and the weight is bigger than 0
// Safety from rep exposure:
// TODO
// All parameters are private and a get method is added
在这里插入图片描述
//构造方法和get函数
在这里插入图片描述
//toString
在这里插入图片描述
2.1.3.2 Implement ConcreteVerticesGraph

Concrete vertices graph的测试也是用GraphInstanceTest,该测试和具体实现无关,在ConcreteVerticesGraphTest中,只需要测试tostring即可
在这里插入图片描述
在这里插入图片描述
//测试覆盖率达到96%
在这里插入图片描述
// Abstraction function:
// TODO
// Vertices stores a collection of all the points to form the graph
// Representation invariant:
// TODO
// Vertices can’t have duplicate points
// Safety from rep exposure:
// TODO
// All parameters are private and a get method is added
// Use defensive copies when necessary
//add
在这里插入图片描述
//set
在这里插入图片描述
在这里插入图片描述
//remove
在这里插入图片描述
//vertices
在这里插入图片描述
//sources
在这里插入图片描述
//targets
在这里插入图片描述
//toString
在这里插入图片描述
2.1.4 Problem 3: Implement generic Graph
泛型,将两个实例类中的所有String类的参数替换为泛型的参数(声明、函数参数、返回值、rep)首先把所有类的类型改成泛型,之后将所有的变量类型表示成泛型.
在这里插入图片描述
2.1.5 Problem 4: Poetic walks
2.1.5.1 Test GraphPoet
在这里插入图片描述
测试:采用mit的测试用例,
在这里插入图片描述
预计生成的结果是expectedstring
在这里插入图片描述
测试覆盖度为82%

2.1.5.2 Implement GraphPoet
// Abstraction function:
// TODO
// Extracts the entered text word as a vertex
// Build a directed graph
// Convert to a poem
// Representation invariant:
// TODO
// Directed graphs are not empty
// Safety from rep exposure:
// TODO
// All fields are private
首先生成一个图。采用edge的存储模式。
在这里插入图片描述
该函数是通过文件,生成一个图。
在这里插入图片描述
首先读取文件,判断是不是文件为空,或者读取文件错误。
在这里插入图片描述
读取文件的每一行内容。然后根据空格分离,匹配一下看是不是有单词和标点构成的。之后存储所有转换为小写的字符串。
在这里插入图片描述
之后利用graph的各个方法,生成一个有向图。根据spec说明,如果有重复的情况,只添加一个顶点,并自己指向自己的权值为后面重复单词的个数。
2.1.5.3 Graph poetry slam
在这里插入图片描述
2.1.6 Before you’re done
在这里给出你的项目的目录结构树状示意图。
在这里插入图片描述
2.2 Re-implement the Social Network in Lab1
这个实验是基于在Poetic Walks中定义的Graph及其两种实现,重新实现L ab1中的FriendshipGraph类。我们需要尽可能复用这个实验是基于在Poetic Walks中定义的Graph及其两种实现,重新实现L ab1中的FriendshipGraph类。我们需要尽可能复用ConcreteEdgesGraph或ConcreteVerticesGraph中已经实现的add0和set()方法,而不是从零开始。另外基于所选定的|ConcreteEdgesGraph或ConcreteVerticesGraph的rep来实现,而不能修改父类的rep。
2.2.1 FriendshipGraph类
在这里插入图片描述
首先FriendshipGraph类继承图ConcreteEdgesGraph类,为了调用所有的方法,包括add,set,remove等等方法
增加三个方法分别是addVertex,addEdge,getDistance,方法
在这里插入图片描述
AddVertex实现将顶点加入该图中,调用ConcreteEdgeGraph的方法,如果已经重复添加过顶点,那么便打印错误信,没有重复添加过,便添加一个顶点。
在这里插入图片描述
addEdge方法实现,在两个顶点中加入边,根据之前实验一中FriendshipGraphspec的说明,在添加边之前必须先加入顶点,所以首先检查边中是否有没添加过的顶点,之后判断是不是在同一个顶点中加入边,最后判断边是否添加过。
在这里插入图片描述
Getdistance方法是判断两点的最短距离,采用广度优先遍历的方法,并采用队列的存储结构,从friend1开始广度优先遍历,首先将第一个顶点加入队列,每次循环删除第一个顶点,之后将与其相连的所有顶点加入队列, 直到遇到目标顶点。并记录层数,如果是第几层,便是最短距离。如果两点之间没有路径到达的话,那么便返回-1;
2.2.2 Person类
Person类比较简单,只是简单记录一下每一个顶点的名称即可。
在这里插入图片描述
只需要构造器,和obsever,能够存储名字及名称即可。
2.2.3 客户端main()
客户端client函数,应该和lab1的客户端不变,因为两个实现方法实现的功能都应该相同,new一个FriendshipGraph类即可,然后添加顶点,添加几条边,并且调用getDistance函数,算出图中各个顶点的距离。
在这里插入图片描述
2.2.4 测试用例
在这里插入图片描述
在这里插入图片描述
//覆盖度为
在这里插入图片描述
2.2.5 提交至Git仓库
在这里插入图片描述
3 实验进度记录

日期 时间段 计划任务 实际完成情况
5.14 8:00-17:00 完成P1.graph 完成
5.16 10:00-20:00 完成P1.poet 完成
5.18 10:00-16:00 完成P2 完成

4 实验过程中收获的经验、教训、感想
4.1 实验过程中收获的经验和教训
了解了面向ADT编程,学会利用泛型提高代码复用性,更适应spec,测试,实现这个代码过程
4.2 针对以下方面的感受
(1)面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
面对ADT更加易于理解,ADT编程相当于对问题进行逐层抽象,而使用面向应用场景编程相当于全局抽象,在ADT的设计的时候,从某种意义上来说只需要关注当前子问题层面,所以容易将问题简单化。
(2)使用泛型和不使用泛型的编程,对你来说有何差异?
泛型对于代码的复用更有利,泛型的适用性无疑更广,功能也很强大,使用泛型也给编程人员提供了更大的活动空间。
(3)在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
更容易发现代码bug
(4)P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
简化编程
(5)为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
使客户不能了解和更改内部的细节,有助于区分责任,让客户理解程序,也能提高代码效率。愿意
(6)关于本实验的工作量、难度、deadline。
挺多的,不过也还可以
(7)《软件构造》课程进展到目前,你对该课程有何体会和建议?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值