软件构造实验三

本次实验的要求是实现轨道系统CircularOrbit,并实现三个具体应用。

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

对于每个轨道系统CircularOrbit<L,E>,L为其中心物体类型,E为其轨道物体类型。

Set<Track> tracks为其轨道集合,Map<E,Track> object_trackMap表示其物体在轨道系统上的分布,L center为其中心物体

 

首先编写CircularOrbit接口。提供以下方法:

读取文件构造轨道系统

 添加轨道(默认如果有n条轨道,则轨道编号分别为1~n的自然数)

 删除轨道

 设置中心物体

 将物体加入指定轨道上

 将物体加入轨道系统且暂不为其分配轨道

 删除轨道物体

 从特定轨道上删除物体

 设置关系

 跃迁(电子从原来的轨道跃迁到新的轨道,认为同一个轨道上的电子是等价的)

 一些get方法

 写一个抽象类ConcreteCircularOrbit来实现具体应用的共同点

 删除轨道时,将编号大于被删除轨道的编号的轨道的编号-1

具体应用

 我选择的应用是TrackGame,AtomStructure和SocialNetworkCircle,均继承上面的ConcreteCircularOrbit

 TrackGame

 读取文件部分,我的正则表达式设计如下

 处理部分(原先是边读取运动员边安排轨道,所以要先知道轨道总数,就拆成两个循环了。后来改成策略模式后就没必要这样了)

 值得注意的是在使用matcher的捕获组group时,要先判断matcher.find,否则会报错

 由于TrackGame无中心物体,故将中心物体设为null

轨道安排在后面的策略模式详细介绍

AtomStructure

正则表达式

 先获取轨道总数

 再获取元素名称、电子排布

 读取电子排布的方式是:先用split获取" ::= "后面的部分,然后用";"进行分隔,写入字符串数组strings1,这样strings1中的每个元素应当是“轨道编号/电子数”的形式,依次读取strings1中的每个元素即可。

SocialNetworkCircle

这里复用了实验二的图,用于表示用户之间的关系。由于实验二中边的权值为整数,而这里的社交亲密度小数点后最多三位,故将权设为(int)(社交亲密度*1000)

正则表达式

 先读取用户信息以建立图的顶点

 再根据关系向图中添加边

 轨道安排,对于一个轨道物体,根据其到中心物体的逻辑距离为其安排轨道

 其中getDistance的设计同实验二

设置关系

 在添加、删除物体时,运行父类的对应方法并更新图。在删除物体或设置关系后也会重新进行轨道安排。

轨道设计

考虑到我选择的三种应用都不记录轨道半径,故轨道类定义如下

 中心物体设计

中心物体定义如下,该定义足以满足TrackGame及AtomStructure的要求。对于SocialNetworkCircle,由于中心物体与轨道物体的属性完全一致故其中心物体采用其轨道物体的类型。

 轨道物体设计

PhysicalObject类,这个类作为Athlete类及Friend类的父类,拥有它们的共同属性。同时作为AtomStructure的轨道物体类。

 Athlete类,作为TrackGame的轨道物体类

 Friend类,作为SocialNetworkCircle的轨道物体类及中心物体类

 可复用API设计

计算熵值

采用公式

其中为方便起见,对数取e为底(其实也可以用换底公式)

具体实现在ConcreteCircularOrbit类中,并在CircularOrbitAPIs类中调用。

 计算逻辑距离

此功能在仅适用于SocialNetworkCircle且在其轨道安排中已经实现并使用。只需在CircularOrbitAPIs中调用即可。

 可视化

这部分个人感觉很难,代码写得可能有些乱,望看官们海涵。

采用java swing来实现此功能。思路是使用自定义控件来绘制轨道系统。

写一个继承JPanal的类作为自定义控件

 重写父类的paintComponent方法以进行绘制。首先均匀地画出轨道,使得相邻的轨道的半径差相等,为delta

 然后根据各轨道上的物体数,计算出各轨道上相邻两物体与圆心连线的夹角大小,从而使每条轨道上的物体均匀地排布

 这里有一个很奇怪的问题,原先按照一周360°计算,发现画出来的轨道物体并不是均匀排布的,比如一个轨道上两个物体,可以推测第二个物体相对于第一个物体转过的角度是240°,如下图的最内侧轨道。将360°改为270°后则达到预期效果。我思考良久也未能理解其原理,还请各位赐教。

接下来绘制中心物体

 对于TrackGame及AtomStructure,这样就完成了。但SocialNetworkCircle还需要画出关系,于是建立一个Map<Friend,Point> position来记录每个轨道物体在界面中的位置,然后再画出关系即可。

在实际使用中,界面需要更新。这里采用的方法是将之前的窗口设置为不可见并新建立窗口。

 设计模式应用

工厂模式

在CircularOrbit接口设置一系列静态工厂方法

 迭代器模式

设置一个迭代器ObjectIterator,可按轨道从内至外的顺序遍历轨道物体

属性,c为其遍历的轨道系统,trackIndex为当前遍历到的轨道编号,objectIndex为当前轨道上遍历到的物体数

 hasNext方法

 next方法

 策略模式

按不同的策略对TrackGame进行轨道安排。首先设置一个抽象类Strategy

 然后写具体的策略,继承上面的抽象类

 在TrackGame中设置一个Strategy对象strategy,进行轨道安排时,调用strategy的trackStrategy即可。设置setStrategy方法以支持切换策略

具体应用开发

通过控制台进行交互,用户输入给定的指令,程序将进行对应的操作,调用上面所实现的功能。此部分基本上是依赖于上面所实现的功能,故不再赘述。

新的变化

TrackGame

添加一个新的策略,RelayRaceStrategy类继承Strategy类

 AtomStructure

由于TrackGame无中心物体,SocialNetworkCircle中心物体是Friend型,故直接修改Center类,添加属性numOfProton和numOfNeutron,分别表示质子数和中子数

 SocialNetworkCircle

原来是在设置关系时加入两条有向边来表示无向关系,修改后在设置关系时只加入一条有向边。

可视化时,只展示低轨道向高轨道或向同轨道间的关系及中心物体到轨道物体的关系

posted @ 2023-05-15 18:43  YY_R  阅读(44)  评论(0)    收藏  举报