计算机学院《软件构造》课程 Lab 2实验
2020年春季学期
计算机学院《软件构造》课程
Lab 2实验报告
目录
1 实验目标概述 1
2 实验环境配置 1
3 实验过程 2
3.1 Poetic Walks 2
3.1.1 Get the code and prepare Git repository 2
3.1.2 Problem 1: Test Graph 2
3.1.3 Problem 2: Implement Graph 2
3.1.3.1 Implement ConcreteEdgesGraph 3
3.1.3.2 Implement ConcreteVerticesGraph 3
3.1.4 Problem 3: Implement generic Graph 3
3.1.4.1 Make the implementations generic 3
3.1.4.2 Implement Graph.empty() 4
3.1.5 Problem 4: Poetic walks 4
3.1.5.1 Test GraphPoet 4
3.1.5.2 Implement GraphPoet 4
3.1.5.3 Graph poetry slam 4
3.1.6 Before you’re done 4
3.2 Re-implement the Social Network in Lab1 5
3.2.1 FriendshipGraph类 5
3.2.2 Person类 6
3.2.3 客户端main() 6
3.2.4 测试用例 6
3.2.5 提交至Git仓库 6
3.3 Playing Chess 8
3.3.1 ADT设计/实现方案 8
3.3.2 主程序MyChessAndGoGame设计/实现方案 9
3.3.3 ADT和主程序的测试方案 10
4 实验进度记录 11
5 实验过程中遇到的困难与解决途径 11
6 实验过程中收获的经验、教训、感想 11
6.1 实验过程中收获的经验和教训 11
6.2 针对以下方面的感受 11
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 实验环境配置
主要在于安装EclEmma插件
标签栏:Help->Eclipse Marketplace->搜索EclEmma,Install;
安装完成后重启,工具栏可以看到Coverage图标即可
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/Lab2-1180300616
3 实验过程
3.1 Poetic Walks
通过实现Graph接口,来完成一个图结构,并使用该结构对诗歌进行润色。
3.1.1 Get the code and prepare Git repository
-
将仓库从Github上clone下来:
shell
git clone https://github.com/rainywang/Spring2019_HITCS_SC_Lab2.git -
将自己的作业仓库clone下来
shell
git clone https://github.com/ComputerScienceHIT/Lab2-1180300616.git -
将所需要的文件夹复制到仓库,并将本地仓库与远程仓库同步:
shell
git add .
git commit -m “…”
git push origin master。
3.1.2 Problem 1: Test Graph
本项目的主要思路是先写测试用例、再实现具体方法,测试用例通过注释中对类和函数功能的说明可以实现。
3.1.3 Problem 2: Implement Graph
Graph接口的两个具体实现:ConcreteEdgesGraph和ConcreteVerticsGraph
3.1.3.1 Implement ConcreteEdgesGraph
用一个Set来存储所有的顶点,用List来存储所有的边
由于边类是不可变的,所以将source、target和weight都置为final。
另外,在实现remove()方法删除一个顶点时,除了需要从set中删除该顶点外,还需要遍历edges来删除所有与被删除顶点相关的边
3.1.3.2 Implement ConcreteVerticesGraph
用一个List来存储所有的顶点,由于无法修改ConcreteVerticesGraph的属性,在Vertex中加入一个Map,来描述顶点与顶点之间边的关系
3.1.4 Problem 3: Implement generic Graph
使用范型来实现
3.1.4.1 Make the implementations generic
将其声明修改为:
public class ConcreteEdgesGraph implements Graph
class Edge
public class ConcreteVerticesGraph implements Graph
class Vertex
即可,另外,所有的String都要改为L
3.1.4.2 Implement Graph.empty()
实例化一个Graph的实现类然后返回即可
3.1.5 Problem 4: Poetic walks
利用上面实现的图进行实践
3.1.5.1 Test GraphPoet
根据注释编写相应测试文件即可
3.1.5.2 Implement GraphPoet
主要需要实现两个方法 -
一个是GraphPoet方法,构造方法参数为一个File(corpus),通过语料库中的语句构建一个图结构,存储语料库中的单词关系,忽略大小写。
-
第二个是poem方法,该方法参数为一个String,通过图结构对该语句进行润色,在必要处添加单词。另外,要注意输入与输出的大小写需要保持一致。
3.1.5.3 Graph poetry slam
可以使用提供的语料库,也可以自定义语料库,我在测试部分(test文件夹)中使用了自定义的语料库,这里没有做修改
3.1.6 Before you’re done
提交文件就是老套路,不再赘述
项目目录结构:
.
├── lib
│ ├── org.hamcrest.core_1.3.0.v20180420-1519.jar.jar
│ └── junit.jar
├── src
│ └── P1
│ ├── graph
│ │ ├── ConcreteEdgesGraph.java
│ │ ├── ConcreteVerticesGraph.java
│ │ └── Graph.java
│ └── poet
│ ├── GraphPoet.java
│ ├── Main.java
│ └── mugar-omni-theater.txt
└── test
└── P1
├── graph
│ ├── ConcreteEdgesGraphTest.java
│ ├── ConcreteVerticesGraphTest.java
│ ├── GraphInstanceTest.java
│ └── GraphStaticTest.java
└── poet
├── source1.txt
├── source2.txt
├── source3.txt
└── GraphPoetTest.java
3.2 Re-implement the Social Network in Lab1
按照原来的思路将其用P1中的类重新构造一遍即可。
3.2.1 FriendshipGraph类
将原来的矩阵换成现在的邻接表即可
3.2.2 Person类
不变
3.2.3 客户端main()
使用原来的代码即可
3.2.4 测试用例
使用原来的测试用例。
3.2.5 提交至Git仓库
项目目录结构:
.
├── lib
│ ├── org.hamcrest.core_1.3.0.v20180420-1519.jar.jar
│ └── junit.jar
├── src
│ ├── P1
│ │ ├── graph
│ │ │ ├── ConcreteEdgesGraph.java
│ │ │ ├── ConcreteVerticesGraph.java
│ │ │ └── Graph.java
│ │ └── poet
│ │ ├── GraphPoet.java
│ │ ├── Main.java
│ │ └── mugar-omni-theater.txt
│ └── P2
│ ├── FriendshipGraph.java
│ └── Person.java
└── test
│ ├── P1
│ │ ├── graph
│ │ │ ├── ConcreteEdgesGraph.java
│ │ │ ├── ConcreteVerticesGraph.java
│ │ │ └── Graph.java
│ │ └── poet
│ │ ├── GraphPoet.java
│ │ ├── Main.java
│ │ └── mugar-omni-theater.txt
│ └── P2
│ ├── FriendshipGraph.java
│ └── Person.java
└── test
├── P1
│ ├── graph
│ │ ├── ConcreteEdgesGraphTest.java
│ │ ├── ConcreteVerticesGraphTest.java
│ │ ├── GraphInstanceTest.java
│ │ └── GraphStaticTest.java
│ └── poet
│ ├── source1.txt
│ ├── source2.txt
│ ├── source3.txt
│ └── GraphPoetTest.java
└── P2
└── FriendshipGraphTest.java
3.3 Playing Chess
3.3.1 ADT设计/实现方案 -
Board和Player相互影响,可以修改各自的参数
-
Action可以修改Player修改Board和Player的参数
-
Game通过Action修改Board和Player的参数
-
Player含有Piece,并记录着Piece的Position
-
Board含有Position,并记录着Position上的Piece
Board、Player之间是可以相互访问和修改参数的,但是用户只能接触到Game,通过Game修改参数信息
3.3.2 主程序MyChessAndGoGame设计/实现方案
在main函数中创建Game对象并初始化、调用
在检测到错误(指定的位置超出棋盘的范围、第一个位置上无棋子、第二个位置上无棋子、两个位置相同、第一个位置上的棋子不是自己的棋子、第二个位置上的棋子不是对方棋子、等)会提示错误并重新指定位置或行为。
例:
3.3.3 ADT和主程序的测试方案
直接调用MyChessAndGoGame对分别测试GoGame和ChessGame的方法进行测试(因为需要测试查看菜单与输出)
4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 计划任务 实际完成情况
2020.3.22 白天 完成P1 完成
2020.3.29 上午 完成P2 完成
2020.4.5 白天 完成P3 完成
2020.4.12 白天 完成实验报告 完成
5 实验过程中遇到的困难与解决途径
遇到的难点 解决途径
每次调用scanner关闭之后都会出bug
System.in只能关闭一次
6 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
6.2 针对以下方面的感受
(1) 面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?
面向ADT编程的代码复用率要高得多,编程效率也要高得多
(2) 使用泛型和不使用泛型的编程,对你来说有何差异?
泛型编写起来要麻烦一些,但是使用范围要广得多
(3) 在给出ADT的规约后就开始编写测试用例,优势是什么?你是否能够适应这种测试方式?
一方面帮助自己理解程序的需求,另一方面可以编写完一个函数就测试一个,提高了debug的效率
(4) P1设计的ADT在多个应用场景下使用,这种复用带来什么好处?
增加代码复用率,提高编程效率
(5) P3要求你从0开始设计ADT并使用它们完成一个具体应用,你是否已适应从具体应用场景到ADT的“抽象映射”?相比起P1给出了ADT非常明确的rep和方法、ADT之间的逻辑关系,P3要求你自主设计这些内容,你的感受如何?
还没有完全适应。自主设计的难度更高一些,但是对自己能力的锻炼也更强,也有助于提高项目质量
(6) 为ADT撰写specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后编程中坚持这么做?
主要是增加数据的安全性吧,肯定要的,因为有很多错误都是因为数据被误访问或者误删除才导致的
(7) 关于本实验的工作量、难度、deadline。
都可以接受
(8) 《软件构造》课程进展到目前,你对该课程有何体会和建议?
希望课程进度跟实验进度匹配吧,总感觉两者不在一个频道
上一篇: 2020春软件构造lab2实验报告
下一篇: 如何更好地学习dubbo源代码