ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HIT 软件构造 LAB2

2021-06-22 09:58:12  阅读:235  来源: 互联网

标签:返回 HIT 实现 Graph 移除 LAB2 3.1 软件 思路


目录

 

 

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

本次实验需要安装EclEmma,直接在Eclipse Marketplace中搜索安装

遵循引导即可完成。

 

在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。

https://github.com/ComputerScienceHIT/HIT-Lab2-1190201003

  1. 实验过程

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

    1. Poetic Walks

这一部分给出了一个Graph的接口。要求编写ConcreteEdgesGraph和ConcreteVerticesGraph两个Graph的实现类,并且编写相应的测试类。在实现过程中,要自行编写规约。

      1. Get the code and prepare Git repository

按照实验手册提供的url,在本地打开git bash,使用git clone命令将远端仓库克隆到本地,以此获取代码。

      1. Problem 1: Test Graph <String>

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

3.1.2.1 实现GraphInstanceTest类

 

     1. testAdd()

思路:按add的规约,按点的等价类划分即可

      2. testSet()

思路:按照set的规约,需要对于权值的大小进行等价类划分,并且对于边是否存在也要进行测试

     3. testRemove()

思路:按remove的规约,按点的等价类划分即可

 

 

    4. testVertices()

思路:按Vertices的规约,按点的等价类划分即可

 

 

    5. testSources()

 

    6. testTargets()

 

结果:只做到这一步其实还不能运行该测试类,因为emptyInstance()还没有实现。完成了后续的工作后,可以得到以下结果

 

     3.1.3Problem 2: Implement Graph <String>

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

​​​​​​​    3.1.3.1Implement ConcreteEdgesGraph

3.1.3.1.1 实现Edge类

为了实现ConcreteEdgesGraph类,首先得实现作为边的Edge类

field:

要构造一个边,需要有起点,终点和权值,因此field由source,target和weight构成:

AF,RI等:

    // Abstraction function:

    //   AF(source)为边的起点

//   AF(target)为边的终点

//   AF(weight)为边的权值

    // Representation invariant:

    //   weight为正整数

//   source和target不为空

    // Safety from rep exposure:

//   source,target和weight设置为了private

//   source,target和weight在返回时采用了防御式拷贝

 

构造方法:

构造方法根据起点,终点和权值来初始化一条边即可;

 

checkRep:

作用:检查RI;

思路:根据所编写的RI依次进行检查即可;

getSource:

返回边的起点;

 

getTarget:

返回边的终点;

 

getWeight:

返回边的权值;

 

toString:

功能:返回边的字符串;

思路:为了方便阅读,采取了“起点--权值->终点”的形式;

3.1.3.1.2 完成ConcreteEdgesGraph类(add,set等方法的规约和Graph接口中完全相同,在报告中不再重复)

 

根据要求,写出AF,RI等:

    // Abstraction function:

    //  AF(vertices)是图中的所有点

    //  AF(edges)是图中的所有边

    // Representation invariant:

    //  所有点都存在于vertices中

    //  所有边都存在于edges中

    //  权值必须为正整数

    // Safety from rep exposure:

    //  vertices和edges都设置为private类型

 //  vertices在返回时使用了防御式拷贝

 

filed:

要构造一个图,需要一个边集合,一个点集合:

构造方法:

直接采取缺省的构造方法

checkRep:

作用:检查RI;

思路:根据所写的RI,逐项进行检查即可;

add:

作用:将一个点加入图中;

思路:检查该点是否在图中。已有的点返回false,新的点加入vertices;

 

set:

作用:将一条新的边加入图中,或者更新一条已有的边的权值,或者移除一条边;

思路:检查weight的值。如果小于0,返回-1;如果等于0,移除该边;如果大于0,将此边加入图中,或者更新该边的权值(取决于这是否是新的边);

实现:以下为weight大于0的情况:采用迭代器来检查是否是新的边,对于需要更新的情况,先移除原边,再加入新的边即可;

 

 

remove:

作用:移除一个点,以及和它有关的边;

思路:检查图中是否存在这个点;如果存在,则移除;如果不存在,返回false;

实现:需要注意的是,以被移除点作为起点和作为终点的边均要移除;

 

vertices:

作用:返回点集合;

实现:采取防御式拷贝

 

 

sources:

作用:返回<起点,权值>构成的map;

思路:构造一个空的map,遍历边集合,将和target匹配的<起点,权值>加入map中即可;

 

target:

作用:返回<终点,权值>构成的map;

思路:同8;

 

 toString:

作用:返回图的字符串;

思路:依次返回每条边的字符串;

3.1.3.1.3 实现ConcreteEdgeGraphTest类

本测试类只需要测试Edge中的方法,其他的方法都在GraphInstanceTest中测试了。

1. testConcreteEdgesGraphtoString():

 

 

  1. testEdgeGetSource():

 

 

  1. testEdgeGetTarget():

 

 

  1. testEdgeGetWeight():

 

 

测试结果:

    ​​​​​​​3.1.3.2Implement ConcreteVerticesGraph

3.1.3.2.1 实现Vertex类

要利用点来构成图,首先要先实现一个表示点的类Vertex

field:

每个点都有一个指向该点的起点集,一个该点指向的终点集以及作为点的标识的名字。集合采用<L, Integer>构成的map来表示,这样还可以记录下权值:

 

AF,RI等:

    // Abstraction function:

    //   AF(name)为点的名字

//   AF(sources)为所有指向该点的点以及对应边的权值

//   AF(targets)为所有该点指向的点以及对应边的权值

    // Representation invariant:

    //   所有点均不为空

//   所有权值均大于0

    // Safety from rep exposure:

    //   name,sources,targets均设置为private

//   返回时采用防御式拷贝

 

构造方法:

按照点的名字进行点的初始化

 

 

checkRep:

作用:检查RI;

 

 

getName:

作用:返回点的名字;

 

getSources:

作用:返回<起点,权值>构成的起点表;

 

getTargets:

作用:返回<终点,权值>构成的终点表;

 

addSource:

作用:在起点表中移除或者加入或者更新一个起点,便于之后实现ConcreteVerticesGraph类中的set方法;

思路:类似set方法。其中移除通过后续编写的removeSource来实现,加入新的点或者更新通过HashMap提供的put方法实现;

 

addTarget:

作用:在终点表中移除或者加入或者更新一个终点,便于之后实现ConcreteVerticesGraph类中的set方法;

思路:同8;

 

 removeSource:

作用:在起点表中删去一个起点;

思路:通过HashMap提供的remove方法实现。不过由于remove方法返回的是Integer,本方法的实际目的是将Integer转化成int。在Integer不是null的情况下,可以将Integer直接赋给int,所以当remove返回null时,我们需要返回0;

 

 removeTarget:

作用:在终点表中删去一个终点;

思路:同10;

 

hashCode和Equals方法直接通过eclipse提供的插件来实现;

3.1.3.2.2 实现ConcreteVerticesGraph类(add,set等方法的规约和Graph接口中完全相同,在报告中不再重复)

 

field:本实现类是基于点来实现的,所以需要一个表示所有点的集合。为了便于检查RI,所以采用了List,而不是Set。

 

 

AF,RI等:

    // Abstraction function:

    //   AF(vertices)为图中所有的点

    // Representation invariant:

    //   vertices中的点不可重复

    // Safety from rep exposure:

    //   vertices设置为private类型

//  vertices在返回时使用了防御式拷贝

 

构造方法:

直接采用缺省的构造方式进行初始化;

 

checkRep:

作用:检查RI;

 

 

add:

作用:在图中加入一个新的点;

思路:通过name来判断该点是否是在图中。如果是已有的点,返回false;如果是新的点,通过name来初始化一个新的Vertex,然后加入图中;

 

set:

作用:将一条新的边加入图中,或者更新一条已有的边的权值,或者移除一条边;

思路:通过Vertex类中的addSource和addTarget方法就很容易实现;

 

remove:

作用:移除图中的一个点,以及和这个点相关的边;

思路:遍历图中的点。如果是该点,则移除;如果是该点的起点,则调用removeTarget方法;如果是该点的终点,则调用removeSource方法;

以下是每次遍历需要执行的内容:

 

vertices:

作用:返回点集合;

思路:由于vertices是List,所以需要再建立一个Set,依次加入点

实现:采取防御式拷贝

 

 

sources:

作用:返回<起点,权值>构成的map;

思路:返回指定点的起点表即可;

 

target:

作用:返回<终点,权值>构成的map;

思路:同8;

 

 toString:

作用:返回图的字符串;

思路:依次返回每条点的字符串;

3.1.3.1.3 实现ConcreteVerticesGraphTest类

 

只需要测试Vertex类中的方法。

 

testConcreteVerticesGraphtoString:

 

 

testGetName:

 

 

testGetSources:

 

 

testGetTargets:

 

 

testAddSource:

思路:按照规约,需要分别就点的等价类和权值的等价类进行划分;

 

 

testAddTarget:

 

 

testRemoveSource:

 

 

testRemoveTarget:

 

 

testEquals:

思路:要测试点是否相等,需要考察起点表,终点表和名字;

 

测试结果如下:

3.1.4 Problem 3: Implement generic Graph<L>

3.1.4.1 Make the implementations generic

将所有之前使用String实现的地方全部修改为泛型实现,然后根据eclipse的语法错误提醒来完成所有的修改;

​​​​​​​3.1.4.2 Implement Graph.empty()

选择一个具体的实现类就行了。这里选择的是使用ConcreteEdgesGraph。

 

补充了对于String,Integer,Float,Character这四种具体类型的测试;

这里的测试策略是利用Collection来创建一个空Set,然后测试empty方法是否也能正常生成一个空Set。

 

至此,已经完成了Graph的两个具体实现类的泛型实现以及测试类。

以下是所有的测试和覆盖率结果;

 

 

其中GraphInstanceTest类的测试结果已经包含在实现类的测试中。

 

 

标签:返回,HIT,实现,Graph,移除,LAB2,3.1,软件,思路
来源: https://blog.csdn.net/ptr0628/article/details/118100056

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有