1 实验目标概述
本次实验覆盖课程第 2、3 章的内容,目标是编写具有可复用性和可维护性
的软件,主要使用以下软件构造技术:
子类型、泛型、多态、重写、重载
继承、委派、CRP
语法驱动的编程、正则表达式
设计模式
本次实验给定了多个具体应用,学生不是直接针对每个应用分别编程实现,
而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其实现,充分考虑
这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可复用性)和更
容易面向各种变化(可维护性)
2 实验环境配置
本次实验环境与前几次相同。
GitHub Lab3仓库的URL地址:https://github.com/ComputerScienceHIT/HIT-Lab3-2021113444
3 实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 待开发的三个应用场景
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
TrackGame
AtomStructure
SocialNetworkCircle
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
TrackGame
TrackGame无中心物体,为轨道系统的组合,轨道数恒定,需要按照一定规则编排轨道物体,轨道物体无运动,物体之间有关系。
AtomStructure
AtomStructure有中心物体,为轨道系统,轨道物体的数量有限制,轨道物体有跃迁,物体之间无关系。
SocialNetworkCircle
SocialNetworkCircle有中心物体,为轨道系统,轨道物体无运动,物体之间有关系,需要考虑关系的改变。
3.2 基于语法的图数据输入
使用正则表达式进行数据的输入,首先不同应用的读取模式不同,所以识别的pattern根据应用更改。
先使用bufferedreader按行读取文件内容,如何根据每个应用输入的不同特征进行捕获组提取,而后从捕获组中获取相关的信息。
再通过这些信息进行图的设置。
3.3 面向复用的设计:CircularOrbit<L,E>
实现如下方法:
addTrack:创建一个空的 CircularOrbit 对象。
deleteTrack:增加一条轨道、去除一条轨道。
addCentralObject:增加中心点物体。
addObjectToTrack:向特定轨道上增加一个物体(不考虑物理位置)。
addRelationCToP:增加中心点物体和一个轨道物体之间的关系。
addRelationPToP:增加两个轨道物体之间的关系。
objectTrans:从外部文件读取数据构造轨道系统对象。
设计ConcreteCircularOrbit实现:
(1) centralObject:中心点物体。
(2) tracks:一组轨道。
(3) objectMap:每条轨道上的一组物体。
(4) relationPToC:中心点物体与轨道物体之间的关系。
(5) relationPToP:轨道物体之间的关系。
(6) objects:所有轨道物体。
3.4 面向复用的设计:Track
考虑到所有的应用中,Track的共用性很高,只需要有半径的变量。
3.5 面向复用的设计:L
中心物体L的具体类设计为:TrackGame的无中心点物体,AtomStructure的中心点物体为原子核,SocialNetworkCircle的中心点物体为人。
原子核设计:只需考虑到元素的名称和质子中子的数量。
人:需要包括年龄,姓名和性别,性别为枚举类。
3.6 面向复用的设计:PhysicalObject
PhsicalObject的设计选用工厂模式,factoryPattern为抽象工厂类,physicalObject为抽象产品类。
TrackGame的physical object为Athlete,包含姓名,年龄,国籍,号码和年度最好成绩。
3.7 可复用API设计
由选取的应用场景来看,选择完成计算系统熵值和计算物体的逻辑距离的功能。
计算多轨道系统中各轨道上物体分布的熵值:根据熵值计算公式entropy=-sigma(pi*log2(pi)),各轨道的熵值累加,最后输出。
计算任意两个物体之间的最短逻辑距离:建立邻接矩阵,并根据relationPtoP和relationPtoC输入边,考虑到轨道物体可以借用中心物体进行联系。然后使用Floyd算法求最短路径并输出。
3.8 图的可视化:第三方API的复用
图的可视化,由于推荐的库Jung\JgraphT\JgraphX等都是画图表的库,这次实验选取swing库。
轨道使用drawoval,取不同的height、width,定圆心,画取同心圆,并且根据轨道数的不同,选取不同的半径增加。
中心物体和轨道物体使用filloval,画实心圆,大小固定。
轨道物体根据数量平均分布在轨道上,并存储物体所在的位置。
中心物体和轨道物体的关系,根据物体的存取的不同的位置,使用drawline画取直线。
3.9 设计模式应用
Factory模式:添加冗余,未添加。
Iterator模式:先建立Iterator接口,要实现方法hasNext(),getNext()。而后定义具体Iterator类,先将轨道物体按轨道位置存入list中,后遍历列list。
Strategy模式:先建立一个strategy接口,实现方法execute(),处理数据并返回处理好的数据。而后实现具体类RandomStrategy,SortedScoreStrategy,分别为随机排序和根据选手分数进行排序。串联的数据是athleteList运动员列表,用户通过setStrategy()来设置strategy,然后调用strategy.execute()对athleteList处理并返回。
3.10 应用设计与开发
3.10.1 TrackGame
TrackGame中包括多个轨道系统,因为要分多个比赛的场次,所以要创建一个轨道系统的列表来储存所有的比赛场次。
首先先从文件中读入所有运动员的信息,因为计划通过运动员的成绩进行比赛的安排,即成绩相近的运动员在一局比赛,所以选用TreeMap,用运动员的最好成绩作为Key,实现自动排序。
而后根据赛道的数量和运动员的数量进行分组。
3.10.2 AtomStructure
实现简单,设置中心物体为元素的名字,读取文件的时候根据轨道数添加轨道,并添加电子。
电子跃迁使用ConcreteCircularCircle中的物体跃迁功能即可,改变ObjectMap的映射,若存在轨道中无物体时,删去轨道。
3.10.3 SocialNetworkCircle
因为要实现关系的图状结构,复用Lab2的graph结构,但是权值要改成double,因为亲密度是小数。
而后读取中心人物、朋友和亲密关系。根据亲密关系完成关系图,添加边。
而后从中心人物开始,进行BFS,每一轮添加一条新的轨道,知道无法搜索。
因为亲密关系中存在环,所以要存储已经读取过的人物。
获得人所在的轨道位置,只需从各个轨道中进行搜索即可。
添加和删去社交关系并重构,先在graph中添加或删去边,而后删去原本的轨道系统,再次设置完成重构。
计算两轨道中用户的逻辑距离,建立邻接矩阵,是用Floyd算法,计算出最短路径并输出。
3.11 应对应用面临的新变化
以下各小节,只需保留和完成你所选定的应用即可。
3.11.1 TrackGame
编排比赛后加入合法性测试。
3.11.2 AtomStructure
编排后加入合法性测试即可。
3.11.3 SocialNetworkCircle
使用getdistance()和所在的轨道层级做比较来完成合法性测试
3.12 Git仓库结构
请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。