软件构造Lab3-实验报告

本次实验旨在通过子类型、泛型、多态等技术,实现可复用和可维护的软件。学生需为径赛方案编排、原子结构可视化和社交网络系统等场景开发抽象数据类型(ADT)和API。实验涉及正则表达式处理输入文件、设计模式如静态工厂、策略、备忘录和建造者模式,并实现图形化界面。
摘要由CSDN通过智能技术生成
  1. 实验目标概述

本次实验覆盖课程第35章的内容,目标是编写具有可复用性和可维护性的软件,主要使用以下软件构造技术:

⚫ 子类型、泛型、多态、重写、重载

⚫ 继承、代理、组合

⚫ 常见的OO 设计模式

⚫ 语法驱动的编程、正则表达式

⚫ 基于状态的编程

 API设计、API 复用

本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构可视化、个人移动App 生态系统、个人社交系统),学生不是直接针对五个应用分别编程实现,而是通过ADT 和泛型等抽象技术,开发一套可复用的ADT 及其实现,充分考虑这些应用之间的相似性和差异性,使ADT 有更大程度的复用(可复用性)和更容易面向各种变化(可维护性)。

  1. 实验环境配置

实验环境设置请参见Lab-0 实验指南。

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

https://github.com/ComputerScienceHIT/Lab3-1173710111

  1. 实验过程

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

    1. 待开发的三个应用场景

首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。

  1. TrackGame
  2. AtomStructure
  3. SocialNetworkCircle

分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。

 

共性:

  1. 系统中的对象:轨道、中心物体、轨道物体。
  2. 物体都不考虑绝对位置。
  3. 轨道都抽象为圆形。
  4. 功能:*创建一个空的CircularOrbit 对象;* 增加一条轨道、去除一条轨道; * 增加中心点物体 ;* 向特定轨道上增加一个物体(不考虑物理位置) ;* 增加中心点物体和一个轨道物体之间的关系 ;* 增加两个轨道物体之间的关系 ;* 从外部文件读取数据构造轨道系统对象 ;* 将object 从当前所在轨道迁移到给定轨道 ;* 将object 从当前位置移动到新的sitha角度所对应的位置。

 

差异:

  1. TrackGame需要构造多个轨道系统,而其他两个只需要构造一个。
  2. TrackGame需要实现编排策略,实现对指定物体交换轨道的功能。

AtomStructure轨道物体彼此之间没有区别,需要实现电子跃迁的功能,并可以实现对跃迁操作的历史记录,以便撤销操作和重做。

SocialNetworkCircle中物体之间存在关系,并能够实现添加和删除的操作,需要计算信息扩散度。

    1. 基于语法的图数据输入

运用正则表达式对读入文件进行信息提取和处理,三个应用数据提取的正则表达式如下:

(1)TrackGame

//提取有效的运动员信息

private Pattern athletePattern=Pattern.compile("Athlete\\s*:\\s*:\\s*=\\s*<\\s*([a-zA-Z]+)\\s*,\\s*(\\d+)\\s*,\\s*([A-Z]{3})\\s*,\\s*(\\d+)\\s*,\\s*(\\d{1,2})(\\.)(\\d{1,2})\\s*>");

//提取有效的比赛项目信息

private Pattern gamePattern=Pattern.compile("Game\\s*:\\s*:\\s*=\\s*([1|2|4]00)");

//提取有效的轨道数目信息

private Pattern tracksPattern=Pattern.compile("NumOfTracks\\s*:\\s*:\\s*=\\s*(([4-9])|(10))");

  1. AtomStructure

//提取有效的元素名称信息

private Pattern elementPattern=Pattern.compile("ElementName\\s*:\\s*:\\s*=\\s*([A-Z]{1})([a-z]?)");

//提取有效的轨道数目信息

private Pattern tracksPattern=Pattern.compile("NumberOfTracks\\s*:\\s*:\\s*=\\s*(\\d+)");

//提取有效的电子数目信息(每个轨道对应一个电子数)

private Pattern electronPattern=Pattern.compile("NumberOfElectron\\s*:\\s*:\\s*=\\s*((\\d+)(\\/)(\\d+)(;?)\\s*)+");

  1. SocialNetworkCircle

//提取有效的中心用户信息

private Pattern centralPattern=Pattern.compile("CentralUser\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*(\\d+)\\s*,\\s*([MF])\\s*>");

//提取有效的其他用户信息

private Pattern friendPattern=Pattern.compile("Friend\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*(\\d+)\\s*,\\s*([MF])\\s*>");

//提取有效的用户关系信息

private Pattern tiePattern=Pattern.compile("SocialTie\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*([A-Za-z0-9]+)\\s*,\\s*([0-1])(\\.[0-9]{1,3})?>");

 

如上提取出有效信息后,再对提取出的字符串分别按照对应格式再用正则表达式进行提取,根据提取出的信息构造中心物体、轨道物体、建立关系等等。

这一部分的功能由抽象类FileReader类实现,该类有三个实例类,分别对应三个具体应用。

FileReader采用静态工厂模式,根据传入的字符串参数(应用类型)来确定返回哪个具体的实例类。

    1. 面向复用的设计:CircularOrbit<L,E>

mutable

  1. constructor

CircularOrbit采用静态工厂模式,传入String型的参数type,返回实例类ConcreteCircularOrbit

public ConcreteCircularOrbit(String type) {

this.type = type;

}

public static <L,E> CircularOrbit<L, E> empty(String type){

CircularOrbit<L, E> circularOrbit=new ConcreteCircularOrbit<L,E>(type);

return circularOrbit;

}

/**

 * 返回给定type对应的多轨道系统。

 * given the type,return a instance.

 * @param type: the type of application->"TrackGame"/"AtomStructure"/"SocialNetworkCircle"

 * @return a new CircularOrbit instance of type. 

 */

 

 

  1. AF:

* 一个轨道系统,由唯一一个中心物体(不是必需)和以其为圆心的若干同心圆轨道组成,轨道上有若干围绕物体mutable

 * AF:

 * 1.一个轨道系统的中心物体->centralObject具有唯一性,Immutable

 * 2.一个轨道系统的圆形轨道->track每个轨道都是Immutable的,可添加多个轨道

 * 3.轨道上的物体->physicalObjectImmutable

 * 4.轨道物体的关系->Graphmutable

 * 5.中心物体与轨道物体的关系->CPGraphmutable

 

  1. RI:

centralObject;

1. 系统的中心物体类型只能为centralObject包中的类,或者String、Integer、Double。一个轨道系统只能有唯一不变的中心物体。

 

List<Track<L>> tracks

2. 系统所有轨道的集合:用List存储,无序

Map<Track<L>, List<E>> objectMap

3. 轨道->轨道上所有轨道物体 的映射:Track->List<E>的映射,key的集合=系统所有track的集合,value是该轨道上所有物体的集合;

Map<E, Track<L>> trackMap

4. 轨道物体->所在轨道 的映射 :E->Track的映射,key的集合=系统所有轨道物体的集合,value是当前该物体所在的轨道;

Graph<E> objectsGraph

5. 轨道物体之间的关系图用Graph来表示轨道物体之间的关系,Graph中的点一定是系统中有的轨道物体;

CentralGraph<L, E> CPGraph

6. 中心物体与轨道物体之间的关系图:新建一个CPGraph对象,以CentralUser为中心点;

String type

7. 系统所属的应用类型只能从三个String--"TrackGame" "AtomStructure" "SocialNetworkCircle"中选择,不区分大小写;

Map<E, Double> positionMap

8. 轨道物体->在轨道上的位置(角度) 的映射当前该物体在其对应轨道上的位置。

 

  1. Safety from rep exposure

所有rep都为private,部分客户端需要的域(如tracks、objectsGraph等),通过get方法进行返回。

 

  1. function:

public boolean addTrack(Track<L> track);

/**

 * 将给定轨道加入系统。

 * add the given track into this system.

 * @param track:the new track to be added.

 * @return 

 * if this track has been existed,return false;

 * if this track is not in this system,return false;

 * otherwise,add it into the system,and return true.

 */

public boolean removeTrack(Track<L> track);

/**

 * 将给定轨道从系统中删除。

 * remove the given track from this system.

 * @param track:the track to be removed.

 * @return 

 * if this track is not existed,return false;

 * otherwise,remove it with all objects on it from the system,and return true.

 */

public boolean addCentralObject(L central);

/**

 * 将中心物体加入系统。

 * add the central object into system.

 * @return

 * if there has been a central object in the system,return false,with nothing to do;

 * otherwise,add it into the system.return true.

 */

public boolean addOrbitObject(Track<L> track,E object);

 

/**

 * 向给定轨道加入给定物体,不考虑物理位置. 

 * @param track

 * @return

 * if the object has been in the given track,return false;

 * if the object has been in another track,return false;

 * otherwise,if the track is not in this system,first add the track,then add and return true.

 */

public boolean removeOrbitObject(E object);

/**

 * 将给定物体从轨道系统中移除

 * @param object

 * @return

 * if the object is not in this system ,return false;

 * otherwise,remove it and return true.

 */

public int addRelationship(E object1,E object2,int weight);

/**

 * 在给定两个轨道物体之间建立一条单向边。

 * add an edge between the two objects.

 * @param object1: source

 * @param object2: target

 * @param weight: the value of edge

 * @return

 * if there have been an edge between the two objects,update the value,return the old value;

 * otherwise,add a new edge,and return 0.

 */

public int addCPRelationship(L central,E physical,int weight);

/**

 * 在给定的中心物体与轨道物体之间建立一条单向边。

 * @param centra

 * @param physical

 * @param weight

 * @return

 */

public int addPCRelationship(E physical,L central,int weight);

/**

 * 在给定的轨道物体与中心物体之间建立一条单向边。

 * @param physical

 * @param central

 * @param weight

 * @return

 */

public FileReader<L, E> readAndBuild(String filename);

/**

 * 从外部文件读取数据构造轨道系统对象

 * Read data from external files to construct system object

 * @param file

 * if the file is non-readable,throw exception and warning.

 */

public boolean transmit(E object,Track<L> track);

/**

 * 将object 从当前所在轨道迁移到给定轨道 

 * move the object to a new given track from current one

 * 

 * if the track is not in this system,add this track into it first.

 * 

 * @param object: the object to be moved

 * @param track: the track that the object should be moved to

 * @return

 * if the object is not on any tracks in this system,add the object into this track,return true.

 * if the track is the same as where the object is on,return false;

 * if the object has been in the given track,return false with nothing to do;

 * otherwise,do the move and return true.

 */

public boolean move (E object,double sitha);

/**

 * 将object 从当前位置移动到新的sitha角度所对应的位置,sitha保留3位小数。

 * move the object to a new given angle from current one

 * @param object: the object to be moved

 * @param sitha: a relative angle between [0,360), stand for where the object should be moved to 

 * @return

 * if the object is not on any tracks in this system,return false;

 * if the object is on the position,return true;

 * otherwise,do the move and return true. 

 */

public L centralObject();

/**

 * @return 

 * the central object of this system;

 */

public List<Track<L>> tracks();

/**

 * @return

 * all tracks of this system,order by radius from small to large 

 */

public Graph<E> getGraph();

/**

 * @return

 * a graph:the relationship between all physical objects

 */

public List<E> objects(Track<L> track);

/**

 * @param trackthe given track must be in this system.

 * @return

 * first put all physical objects which are on this track,order by position(angle) from small to large in the list,

 * then put all no-position objects in it. 

 */

 

  1. 辅助类
  1. .1 Tool

public double getPosition(E object,Map<E, Double> positionMap)

/**

 * 给定一个变量object,给定位置映射positionMap,返回object对应的位置信息。

 * @param object

 * @param positionMap

 * @return如果Map中没有该物体对应的位置信息,返回false,否则返回其对应的Map中的value域

 */

ConcreteCircularOrbit类中,需要获取轨道物体的位置信息的行为被委托给Tool的getPosition方法执行。

public boolean addPosition(E object,Double sitha,Map<E, Double> positionMap)

/**

 * 给定一个变量object,一个位置信息sitha,建立object->sitha的映射并将其加入给定Map中。

 * @param object

 * @param sitha

 * @param positionMap

 * @return

 * 如果sitha在[0.0,360.0)范围内,建立映射并加入Map中,返回true;

 * 否则直接返回false

 */

ConcreteCircularOrbit类中,需要将轨道物体固定在某个位置的行为被委托给Tool的addPosition方法执行。

public List<E> getObjectsWithPos(Track<L> track,Map<E, Double> positionMap)

/**

 * 给定一个轨道Track,给定位置映射Map,将Track上的所有轨道物体按照其在Map中的绝对位置从小到大排序,然后返回排好序的物体集合。

 * @param track

 * @param positionMap

 * @return

 */

ConcreteCircularOrbit类中,需要获取拥有绝对位置的轨道物体集合,并将其按从大到小排序,的行为被委托给Tool的该方法执行。

 

(6).2 UseForComparator<E>

class UseForComparator<E>{

private E label;

private double position;

 

public UseForComparator(E object,double sitha) {

this.label=object;

this.position=sitha;

}

 

E getLable() {

label=this.label;

return label;

}

 

double getPosition() {

double position=this.position;

return position;

}

}

/**

 * 用于辅助排序的辅助类,提供两个域,将泛型的physicalObject与其在轨道上对应的位置封装到一起,以便于构造Comparator

 * @author 1173710111

 *

 * @param <E>

 */

 

6.(3) ObjectComparator<E>

class ObjectComparator<E> implements Comparator<UseForComparator<E> >{

 

@Override

public int compare(UseForComparator<E> o1,UseForComparator<E> o2) {

if (o1.getPosition()>o2.getPosition())

return 1;

else if(o1.getPosition()==o2.getPosition()) return 0;

else return -1;

}

 

}

排序接口

 

    1. 面向复用的设计:Track
  1. constructor

public Track(L belong,int label,double radius) {

this.belong=belong;

this.label=label;

this.radius=radius;

 

  1. AF:

/**

 * AF:Immutable 

 * 1.轨道所属的系统->belong类型只能为centralObject包里定义的类,唯一确定,Immutable

 * 2.轨道的标签->labelImmutable

 * 3.轨道的半径->radiusImmutable

 * @author 1173710111

 *

 */

 

  1. RI

private L belong;

1.轨道所属的系统:用系统的centralObject表示

private int label;

2.轨道的标签:用一个整型变量表示,代表轨道的序号,在一个系统里每个轨道的标签是唯一且独一无二的。

private double radius;

3.轨道的半径:用一个大于等于0.0的双精度浮点数表示,轨道的半径决定了轨道之间的次序。

 

  1. Safety from rep exposure

Track类的所有rep都为private标识的,客户端只能通过constructor为其赋初始值,再次调用时只能通过getter方法获取,不能修改。

 

  1. function

三个rep的getter方法

public String toString(){

String string = "< " + this.belong.toString() + ", " + this.label + ", "+this.radius+">";

return string;

}

public boolean equals(Track<L> track{

if (this.toString().equals(track.toString()))

return true;

else

return false;

}

 

    1. 面向复用的设计:L
  1. Nucleus: AtomStructure中心点物体原子核

rep:

private String elementName;

private int numberOfTracks;

function:

三个域的getter

public boolean equals(Nucleus e) {

if (this.elementName.equals(e.getElementName()))

return true;

else

return false;

}

 

  1. CentralUser:SocialNetworkCircle中心点物体人

rep:

private String name;

private int age;

private char sex;

function:

三个域的getter

public String toString() {

String string="<"+this.name+", "+this.age+", "+this.sex+">";

return string;

}

public boolean equals(CentralUser user) {

if (this.toString().equals(user.toString()))

return true;

else

return false;

}

 

    1. 面向复用的设计:PhysicalObject

(1)抽象类PhysicalObject,包含了三个应用的PhysicalObject公有的域和方法:

rep:

protected String name;

 

protected int x;

PhysicalObject在画布上的横坐标

protected int y;

PhysicalObject在画布上的纵坐标

function:

//各子类按照自己的域对toString方法进行重写

public String toString() {

String string="";

string=string+"<"+this.getName()+">";

return string;

}

public boolean equals(PhysicalObject o) {

if (this.toString().equals(o.toString())) return true;

else return false;

}

  1. 针对三个应用类,PhysicalObject衍生的三个实例子类:

Athlete:

rep:

private int age;

private int number;

private String nationality;

private double bestScore;

function:

@Override

public String toString() {

String string=new String("<");

string=string+this.getName()+",";

string=string+this.getNumber()+",";

string=string+this.getNationality()+",";

string=string+this.getAge()+",";

string=string+this.getBestScore()+">";

return string;

}

Electron:

电子可以认为彼此之间没有区别,不需要添加其他域和方法。

 

User:

rep:

private char sex;

private int age;

function:

@Override

public String toString() {

String string="<"+this.name+", "+this.age+", "+this.sex+">";

return string;

}

 

    1. 可复用API设计

CircularOrbitAPIs<L, E>

基于所选定的三个应用构造的具体的多轨道结构,可在其上开展一系列共性计算

public double getObjectDistributionEntropy(CircularOrbit<L, E> system)

/**

 * 计算多轨道系统中各轨道上物体分布的熵值.

 * 每一条轨道上的物体数目/轨道系统所有物体数目作为p,使用entropy=-sigma(pi*log2(pi))公式计算轨道系统熵值。

 * @param system

 * @return

 */

public int getLogicalDistance(CircularOrbit<L, E> system, E object1, E object2)

/**

 * 使用BFS算法计算给定的两个物体之间的逻辑距离:这里的逻辑距离是指:两个object 之间通过最少多少条边(relation)即可连接在一起。

 * 两个物体之间若无关系,则距离无穷大。

 * 给出的两个object必须是在给定system中的。

 * @param system

 * @param object1

 * @param object2

 * @return

 * 如果两个object之间不连通,返回-1表示距离无穷大,否则返回两点间的最短路长。

 */

在三个应用中不考虑物理位置,不需要实现

获取物理距离

Different<L, E> getDifferent(CircularOrbit<L, E> system1, CircularOrbit<L, E> system2)

/**

 * 计算两个多轨道系统之间的差异。两个system必须为同类型的轨道系统。

 * @param system1

 * @param system2

 * @return

 * 一个Different变量,内部保存了两个系统差异的相关信息。

 */

Different类:

  1. constructor:

public Different(CircularOrbit<L, E> system1, CircularOrbit<L, E> system2) {

this.system1 = system1;

this.system2 = system2;

setTrackNumberDifferent();

setObjectNumberDifferent();

setObjectDifferent();

}

 

  1. AF:

/**

 * 表示两个系统之间差异的类,需要表达出:

 * 1.轨道数的差异->trackNumberDifferent

 * 2.有相同次序的轨道上物体数量的差异->objectNumberDifferentMap

 * 3.物体的差异(如果物体不需要区分,则无需给出物体的差异)->objectDifferentMap

 * 两个系统必须为同类型的轨道系统才可以比较。

 * @author 1173710111

 *

 * @param <L>

 * @param <E>

 */

 

  1. RI:

private CircularOrbit<L, E> system1;

 

* 1.用于比较的两个轨道系统:由构造器根据读入参数赋值,两个系统必须具有相同的类型参数。

 

private CircularOrbit<L, E> system2;

 

private int trackNumberDifferent = 0;

 

* 2.轨道数的差异:用系统1的轨道数-系统2的轨道数得到,可正、可负、可为0,整型变量

 

private Map<Integer, Integer> objectNumberDifferentMap = new HashMap<Integer, Integer>();

 

 * 3.轨道标签(序号)->两个系统对应的轨道上物体数量的差:key集合为两个集合的所有轨道标签的并集,value值可正可负可为0 

private Map<Integer, String> objectDifferentMap = new HashMap<Integer, String>();

* 4.轨道标签(序号)->两个系统对应的轨道上表示物体的差异的字符串:key集合如上。

 

(4)Safety from rep exposure

1.所有rep都为private标识的,客户端只能通过constructor为两个system赋初始值

2.另外三个rep是通过三个private标识的set方法进行计算和赋值,客户端只能通过getter方法获取,不能修改。

3.getter方法内部根据rep构建一个新的变量,使其与原rep值相同但内存不同,这样客户端就不能对rep进行修改。

 

  1. function:

private void setTrackNumberDifferent()

/**

 * 计算两个系统轨道数的差异=系统1的轨道数-系统2的轨道数。

 */

private void setObjectNumberDifferent()

/**

 * 计算两个系统中有相同次序的轨道上物体数量的差异(系统1-系统2)。

 * 如果序号为x的轨道只在系统1中出现,则对应的差异值=系统1中x对应轨道的物体数-0;

 * 如果序号为y的轨道只在系统2中出现,则对应的差异值=0-系统2中x对应轨道的物体数;

 */

private void setObjectDifferent() 

/**

 * 一个轨道上有多个物体且需要区分,这种情况下表达“物体差异”可以用类似于集合的形式,

 * 例如{a,b,c}-{d,f}意味着前者的该轨道上有a\b\c 三个物体没有在后者的同序号轨道上出现,

 * 而后者有d\f 两个物体没有在前者出现。

 */

private String setToString(Set<E> set)

/**

 * 给定一个集合,将集合中的所有元素串成一个字符串

 * 字符串的两端加大括号,各元素以“,”分隔。

 * @param set

 * @return

 */

 

    1. 图的可视化:第三方API的复用

本实验中使用Swing实现可视化功能。同时,在简单的轨道系统可视化基础上,添加了一部分简单控件用于优化交互体验。

程序入口主函数在applications包的application.java文件中生命,调用并创建一个新的gui包的Menu类,在这个类里调用三个具体应用类,来实现可视化功能。

(1)主界面

单击下三角,选择应用类型

  1. TrackGame

鼠标点击“交换”按钮:

  1. AtomStructure

跃迁:

  1. SocialNetWorkCircle

 

查询:

添加:

删除:

    1. 设计模式应用

(1)CircularOrbit等对象使用静态工厂方法实现,在类中设计empty静态方法获得对象。

(2)TrackGame

实现strategy设计模式。设计接口类TrackGame,声明编排分组、交换道次、获取系统三个方法,具体实现交给不同编排策略的实例类完成。

分别实现具体策略类,随机编排TrackGameRandom,按bestscore排序编排TrackGameOrder。

(3)AtomStructure

 实现Memento设计模式管理电子跃迁的状态。

设计Record类,保存电子轨道跃迁信息,分别保存跃迁电子electron,源轨道fromTrack,目标轨道toTrack。

设计Memento类,负责保存所有的跃迁操作列表,撤销信息列表,提供如下功能: * 1.判断两个列表是否为空 * 2.添加一个新的跃迁/撤销操作 * 3.弹出上一个跃迁/撤销操作

(4)SocialNetworkCircle

构造使用builder设计模式,设计辅助类Tool包括addUsers,getTrackNumber,buildTracks,通过传入的参数添加轨道系统组成。

    1. 应用设计与开发

利用上述设计和实现的ADT,实现手册里要求的各项功能。

以下各小节,只需保留和完成你所选定的应用即可。

      1. TrackGame

 * TrackGame:功能1:给定n 个运动员,自动编排比赛方案(分组、排道次),

 * 实现2 种方案(方案1:完全随机;方案2:根据运动员的本年度最好成绩从高到低排序,排名越靠前,则出场越晚,且更占据中央的赛道);

 * 功能2:手工调整比赛方案(为两个选手更换赛道、更换组)

TrackGame类设计为接口,根据传入参数来确定返回哪个实例类,对应相对的编排方案。

  1. constructor:

public static <L,E> TrackGame<String,Athlete> builder(String filename,String type){

TrackGame<String, Athlete> trackGame;

switch (type.toLowerCase()) {

case "order":

trackGame=new TrackGameOrder<L,E>(filename);

break;

default:

trackGame=new TrackGameRandom<L,E>(filename);

break;

}

return trackGame;

}

 

  1. AF:

/**

 * AF:

 * 1.跑道->轨道->Track

 * 2.运动员->轨道物体->PhysicalObject->Athlete

 * 3.跑道数->每个系统的轨道数

 * 4.跑道的内外->半径的大小

 * 5.编排比赛方案->构造轨道系统->divideGroups()

 * (1)分组->构造多个轨道系统

 * (2)排道次->将每个PhysicalObject安排到合适的Track上

 */

 

  1. function:

public List<CircularOrbit<String, Athlete>> systems()

/**

 * get the circular orbit systems.

 * @return

public void divideGroups();

 /**

  * 对运动员进行分组,除了最后一组,每组的人数与赛道数相同,每个赛道只有一个人。

  * 最后一组的运动员按赛道从内到外分布。

  * Make those athletes grouped, with the exception of the last group, each group has the same number of tracks, with only one person per track. 

  * The final group of athletes were distributed from inside to outside by track.

*/

public boolean change(Athlete athlete1, Athlete athlete2);

/**

 * 给出两个运动员,将两个人的道次进行交换。

 * pre-condition:给定的两个运动员必须是参加同一个比赛的(同一个文件读入),可以属于不同小组,可以是同一个人。

 * post-condition:给定的两个运动员是同一个人时不进行交换;否则,如果他们在同一个组,仅交换道次;否则,交换两个人的小组和在小组中的道次。

 * @param athlete1

 * @param athlete2

 * @return

 * if the given athletes are the same one, return false;

 * else return true.

 */

 

两个实例类:

1. TrackGameRandom<L,E>

  1. constructor:

  public TrackGameRandom (String filename) {

     readersystem.readAndBuild(filename);

}

 

  1. RI:

private FileReader<String, Athlete> reader;

 

 

private List<CircularOrbit<String, Athlete>> systemsList = new ArrayList<CircularOrbit<String, Athlete>>();

 

存储分好的组,即构造好的轨道系统

private CircularOrbit<String, Athlete> system = CircularOrbit.empty("TrackGame");

用来获取处理文件用的FileReader

 

  1. function:

 @Override

public void divideGroups() 

/**

     * 分组方案1:随机分组

     */

 

2. TrackGameOrder<L,E>

(1)constructor:

  public TrackGameRandom (String filename) {

     readersystem.readAndBuild(filename);

}

 

(2)RI:

private FileReader<String, Athlete> reader;

 

 

private List<CircularOrbit<String, Athlete>> systemsList = new ArrayList<CircularOrbit<String, Athlete>>();

 

存储分好的组,即构造好的轨道系统

private CircularOrbit<String, Athlete> system = CircularOrbit.empty("TrackGame");

用来获取处理文件用的FileReader

 

(3)function:

@Override

public void divideGroups()

/**

 * 按方案2进行分组,除了最后一组,每组的人数与赛道数相同,每个赛道只有一个人。

 * 最后一组的运动员按赛道从内到外分布。

 * Grouped by scenario 2, with the exception of the last group, each group has the same number of tracks, with only one person per track. 

 * The final group of athletes were distributed from inside to outside by track.

 */

 

 

      1. AtomStructure

 * 根据文件提取到的信息构造一个轨道系统来表示一个元素的原子,并可实现下述功能:

 * 给定源轨道、目标轨道,模拟电子跃迁。

 * 实现Memento设计模式管理电子跃迁的状态。

  1. AF:

/** AF:

 * 1.原子核->CentralObject->Nucleus

 * 2.电子->PhysicalObject->Electron

 * 3.电子层->Track

 * 4.电子跃迁->physicalObject改变所在轨道->transmit

 */

 

  1. RI:

private CircularOrbit<Nucleus, Electron> system=CircularOrbit.empty("atomstructure");

* 1.构造的原子系统:类型为atomstructure,所有跃迁和相关的操作都在这个系统中完成。

private Map<Track<Nucleus>, Integer> volumMap=new HashMap<Track<Nucleus>, Integer>();

* 2.轨道->对应电子数 的映射:文件信息中给出的轨道和对应电子数是在builder中建立map,如果有电子跃迁到其他轨道,则在跃迁时建立新的映射。

private FileReader<Nucleus, Electron> reader;

 * 3.读文件、构造系统用的FileReader

private Memento memento=new Memento();

* 4.保存这个系统与跃迁有关的所有操作的Memento对象:每个原子系统拥有唯一的memento

 

 

  1. function:

public CircularOrbit<Nucleus, Electron> getSystem()

/**

 * 获取构造好的轨道系统

 * @return

 */

public void builder() 

/**

 * 根据提供的文件,读入相关信息,构造原子系统

 */

public Track<Nucleus> getTrack(int index)

/**

 * 给定一个电子层数,获取对应的电子层(轨道)

 * @param index

 * @return

 * 如果给定的index非法(系统中不存在对应的轨道),返回空指针null

 */

public int getVolum(Track<Nucleus> track

/**

 * 给定一个电子层轨道,获取当前该电子层含有的电子数

 * @param track

 * @return

 * 如果给定的轨道不在该系统内,返回值为0

 */

public boolean transmit(Track<Nucleus> track1,Track<Nucleus> track2)

/**

 * 给定源轨道、目标轨道,模拟电子跃迁。

 * @param track1

 * @param track2

 * @return

 * 如果源轨道没有电子,返回false;

 * 否则,模拟跃迁,记录这一操作并返回true

 */

public void undoTyping()

/**

 * 撤销上一步的跃迁操作

 */

public void undoTyping(int step)

/**

 * 撤销上n步的跃迁操作

 * @param step

 */

public void redoTyping()

/**

 * 重做上一次撤销的跃迁操作

 */

public void redoTyping(int step)

/**

 * 重做上n次撤销的跃迁操作

 * @param step

 */

 

  1. 辅助类:
  1. Menmeto(Mutable):

/**

 * 保存所有的跃迁操作列表,撤销操作列表,提供如下功能:

 * 1.判断两个列表是否为空

 * 2.添加一个新的跃迁/撤销操作

 * 3.弹出上一个跃迁/撤销操作

 */

 

  1. Record(Immutable):

/**

 * 记录一次跃迁操作的信息:跃迁的电子,源轨道和目标轨道

 */

 

      1. SocialNetworkCircle
  1. constructor

public SocialNetworkCircle(String filename) {

reader = system.readAndBuild(filename);

}

 

  1. rep:

private CircularOrbit<CentralUser, User> system = CircularOrbit.empty("socialnetworkcircle");

private FileReader<CentralUser, User> reader;

 

  1. function:

public void builder()

/**

 * 从社交关系日志中恢复该结构

 */

public CircularOrbit<CentralUser, User> getSystem()

/**

 * 获取构造好的社交关系系统

 * @return

 */

protected void addUsers()

/**

 * 从文件中读取中心用户信息,并作为中心物体加入系统

 * 从文件中读取用户信息,并作为轨道物体加入系统

 */

protected void buildGraph()

/**

 * 根据文件中提取的信息构造社交关系图

 */

protected Map<User, Integer> getTrackNumber(Graph<User> graph)

/**

 * 根据提供的人物关系图,确定每个用户应在的轨道次序

 * @param graph

 * @return

 */

protected void buildTracks()

/**

 * 根据每个用户对应的轨道次序的映射,构造系统的外层轨道,并将轨道物体放置在正确的轨道上

 */

public double diffusance(User user0)

/**

 * 计算某个处于第一条轨道上的某个好友的“信息扩散度”(即通过该好友可以间接认识多少个朋友)

 * @param user0

 * @return

 */

public void addRelationship(User userdouble weight)

 * 在中心用户与给定用户之间建立权值为weight的双向边

 

public void addRelationship(User user1, User user2double weight)

* 在给定用户之间建立权值为weight的双向边

public void removeRelationship(CentralUser centralUser, User user)

 * 删除给定中心用户与给定用户之间的边

public int getDistance(User user1, User user2

* 计算给定两个用户之间的逻辑距离

 

  1. 辅助类class Tool 

addUsers,buildGraph,getTrackNumber,buildTracks方法委托给Tool的同名方法实现

    1. 应对应用面临的新变化

以下各小节,只需保留和完成你所选定的应用即可。

      1. TrackGame
      2. AtomStructure
      3. SocialNetworkCircle
    1. Git仓库结构

请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值