计算机学院《软件构造》课程 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

  1. 将仓库从Github上clone下来:
    shell
    git clone https://github.com/rainywang/Spring2019_HITCS_SC_Lab2.git

  2. 将自己的作业仓库clone下来
    shell
    git clone https://github.com/ComputerScienceHIT/Lab2-1180300616.git

  3. 将所需要的文件夹复制到仓库,并将本地仓库与远程仓库同步:
    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
    主要需要实现两个方法

  4. 一个是GraphPoet方法,构造方法参数为一个File(corpus),通过语料库中的语句构建一个图结构,存储语料库中的单词关系,忽略大小写。

  5. 第二个是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设计/实现方案

  6. Board和Player相互影响,可以修改各自的参数

  7. Action可以修改Player修改Board和Player的参数

  8. Game通过Action修改Board和Player的参数

  9. Player含有Piece,并记录着Piece的Position

  10. 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) 《软件构造》课程进展到目前,你对该课程有何体会和建议?
希望课程进度跟实验进度匹配吧,总感觉两者不在一个频道

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值