5/1/2019 update:没有考虑Lab4 和Lab5;GUI实现有待改进。
5/5/2019 update:正则表达式错误修改
5/18/2019 update:Atom-RE 再修改
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
共性:
差异:
以下分别是三个应用的在输入处理中设计的正则表达式:
TrackGame:
AtomStructure:
SocialNetworkCircle:
(socialTiePattern最后一项没有排除0,需要另加判断)
对于在文件中读入的每一行,尝试用不同的pattern进行匹配并进行对应的处理(包括split),如果不能匹配则抛出运行时异常MyExp(自定义异常)。
其中SocialTie的正则表达式中用到了?:代表该括号是一个非捕获组,对于有多个括号的捕获情况,捕获顺序是从左到右,从外到内(嵌套)。
类的域:
域名 |
作用 |
L centralObject |
中心物体 |
Map |
轨道->轨道上物体的映射 |
List |
中心物体与其朋友的关系 |
Map |
轨道物体与周围朋友的关系 |
方法以及实现:
方法名 |
方法实现 |
Public Boolean addTrack(Track newTrack) |
向physicalObjectMap中添加新轨道 |
Public Boolean removeTrack(Track rmTrack) |
从physicalObjectMap中删除轨道,轨道上物体随之被删除,调用removePhysicalObject。 |
Public void addCentralObject(L co) |
添加中心物体 |
Public void AddPhysicalObj2Track(E po,Track tk) |
向轨道tk上添加新物体po,修改relOf2TraObjs |
Public void removePhysicalObject(E po) |
在轨道系统中删除轨道物体po,需要在关系表中删除所有与之相关的关系 |
Public void addRelationOfCentralObj2TrackObj(L co,E po,double weight) |
向relOfCob2TraObj中添加关系 |
Public void remove RelationOfCentralObjs2TraObj(L eo,E po) |
在relOfCob2TraObj中删除该关系。 |
Public boolean addRelationOf2TrackObs(E po1,E po2,double weight) |
在relOf2TraObjs添加该关系 |
Public Boolean removeRelationOf2TrackObs |
在relOf2TrackObs中删除该关系 |
Public void transit(E oldObj,E newObj,Track t) |
将原来的轨道物体oldObj(Immutable)修改基本信息后生成的新物体newObj放到轨道t上。 |
Public void move(E oldObject,E newObject) |
将原有的轨道物体oldObject修改基本信息为新的轨道物体newObject。 |
Public double getObjectDistributionEntropy() |
获取轨道系统的熵值,每一条轨道上的物体数目/轨道系统所有物体数目作为p,使用entropy=-sigma(pi*log2(pi))公式计算轨道系统熵值。 |
Public int getLogicalDistance(E e1,E e2) |
使用BFS算法计算e1和e2之间的逻辑距离。 |
Public Difference getDifference(CircularOrbit |
获得自身轨道系统与同类型轨道系统that之间的系统差异。获得两者经过排序之后的轨道(这里的轨道比较按照由内向外因此比较而不是按照半径相等对应比较),将进行比较的两轨道传入Difference对象中,交给Difference对象处理。最后返回Difference对象。 |
Public Boolean checkOrbitAvailable() |
检查系统是否合法,直接返回true交给具体应用系统进行重写。 |
Public Iterator |
返回iterator迭代器。 |
注意到实验要求中的文件读入是不符合本实验中三个应用的共性的,因为TrackGame需要读入多个轨道系统,于是另设计构造类分别为TrackGame,AtomStructure,SocialNetworkCircle,负责读入文件,调用builder构造轨道系统(因此构造类中包含具体轨道系统的引用),负责作为GUI与Orbit轨道系统中的桥梁(获得Orbit基本信息,响应GUI事件,刷新GUI显示信息)。
Immutable类。只有一个radius域。
方法:
getter,静态工厂方法getInstance,compareTo(Comparable接口),equals,hashCode。
其中,覆盖equals方法,Track使用Radius判断两个Track是否相等。
构造CommonObject作为CentralObject和PhysicalObject的父类。其中包括obName与pos分别代表物体名称以及物体位置,Position是Immutable类型。
方法:getter,drawGraphics,hashCode,toString
声明:Public void drawGraphics(Graphics g,GraphicsPainter painter):接受Graphics类与画笔信息类在g上根据画笔信息画出物体,所谓画笔信息类是一个mutable类,承载物体中心在g上的位置、物体绘制颜色、字体信息。在物体类中声明绘制方法是想将具体绘制方法委托到具体的类,而不是通过获取物体信息然后统一绘制。
Immutable对象类。CentralObject继承自CommonObject。
方法:getter,equals
Immutable类,继承自CommonObject。(没有设计为抽象类)
方法:equalsObject,compareTo(Comparable接口)
声明:1)public boolean equalsObject(Object obj),比较当前object与obj是否值相等,这里不覆盖equals,equals依旧是通过内存地址判断相等。
在ConcreteCircularOrbit中我们将两个对应的轨道物体集合添加到Difference对象中。下面声明Difference的类设计。
每一对比较的轨道,各自形成集合且只保留各自轨道上独有的轨道物体(去除交集,这里的比较使用equalsObject进行值比较),通过两个集合构造trackDifference对象,一个轨道系统的Difference由多个trackDifference构成。在trackDifference中提供toString方法将差异转化为字串,需要注意的是,如果两个集合都为空则说明两轨道上物体完全相同,这时候不输出“物体差异”。
本实验中使用Swing实现可视化功能。同时,在简单的轨道系统可视化基础上,添加了一部分简单控件用于优化交互体验。GUI如图1-4(图4显示了实现了在添加新物体时的GUI面板设计,验收的时候出了点问题)
图1. TrackGame轨道系统GUI实现
图2. AtomStructure轨道系统GUI实现
图3.SocialNetwork轨道系统GUI实现
图4. TrackGame轨道系统——添加新轨道物体功能面板
GUI实现思路:
GUI实现缺点:
布局类(目测)不能继承,所以需要分别实现三个布局类,所以需要分别实现三个构造类,冗余代码比较多。
没有实现错误处理,只能应对合法操作。(错误提示可以通过捕获操作异常MyExp进行弹窗来完成)
每个具体应用类的Builder继承自ConcreteCircularOrbitBuilder,覆盖createConcreteCircularOrbit方法分别创建对应的轨道系统对象。
3)Iterator设计模式。设计MyIterator类,构造方法中传入轨道系统的PhysicalObjectMap(保护),首先按照轨道排序,之后按照轨道物体位置排序(因为不考虑轨道物体绝对位置,所以不予实现),在其中添加一个迭代下标,hashNext判断下标是否越界,next移动下标后返回值。
4)façade设计模式,实现API类。
实现strategy设计模式。
设计接口类AssignmentStrategy,其中只有一个List
分别实现具体策略类,简单编排SimpleStrategy,随即编排RandomStrategy,按bestscore排序编排SortedScoreStrategy。具体类中实现assign函数。
实现Memento设计模式管理电子跃迁的状态。
设计ElectronTransitMemento类,保存电子轨道跃迁信息,分别保存跃迁电子electron,源轨道fromTrack,目标轨道toTrack。
设计ElectronTransitCareTaker类,负责保存所有的动作列表,回退历史信息(返回删除点之后的所有操作列表)。回退动作先从CareTaker类中获得删除点之后的所有历史信息,然后传入轨道系统中反方向执行操作。
不需要实现设计模式
功能1:分别将划分轨道系统和轨道的任务委托给RandomStrategy与SortedScoreStrategy完成编排任务。
功能2:调整比赛方案,输入两个运动员的名称(这里假定了每个运动的名称都各不相同),调整轨道:调用在某一轨道上删除/添加一个物体的函数即可完成操作;调整轨道系统:首先需要找到各自的轨道系统、轨道,然后在其中删除目标物体,然后将两个物体分别添加到对方的轨道系统的轨道上。
判断合法性:按照要求实现。
功能:模拟电子跃迁。调用ConcreteCircularOrbit中实现的transit函数即可。
判断合法性:无。
功能1:从社交关系日志中恢复结构,首先将所有的输入信息读入,这时候我们得到了中心节点,与中心节点相邻的节点,节点之间的关联信息,在这个图上进行BFS,BFS的起始节点集合是所有与中心点相邻的节点,于是我们就可以获得哪些节点与中心节点不相邻(删去),各自的节点应该处于哪一条轨道上。之后调用Builder构造轨道系统即可。
功能2:计算第一条轨道上的亲密度因素:这里我们定义第一层轨道上的物体为V,其他物体为U,记v->u路径上紧密度的乘积为val(v,u),则v的扩散度为其所有能到达的物体u’的val(v,u’)之和。使用BFS,这里BFS一次的源点为一个第一层轨道上的物体,对每个第一层轨道上的物体都进行一次BFS。
功能3:增加/删除一条社交关系。增加删除关系可以直接调用ConcreteCircularOrbit中实现了的函数,不过考虑到关系改变会引起图的结构的改变(有的节点需要删除,有的节点需要改变所处的轨道),需要调用adjustFriendLocation来调整整个physicalObjectMap,这里采用的(暴力)方法是重复功能1中的BFS过程,重新计算所处轨道,然后删除不能连通的节点。
功能4:计算逻辑距离。调用ConcreteCircularOrbit中的getLogicalDistance即可。
对于应用三,删除轨道上的物体同样会引起图结构的改变,只需要调用ConcreteCircularOrbit中方法后重新调整图结构即可。
判断合法性:按照要求实现。
4人一个轨道:添加编排策略RelayRaceStrategy,每个轨道分配4个人。修改visualizeContentPanel方法一个轨道上显示全部的人。
修改后如图5.
图5 调用RelayRaceStrategy之后编排
原子核表达为多个质子和多个中子的组合:设计中子质子类,更改AtomCore,添加中子质子列表。修改AtomCore,覆盖drawGraphics方法,改一下AtomCore的显示字符串为多少个中子质子的组合。
具体显示如图6。
图6. 修改之后显示原子核组成
为关系增加方向性:在原来的实现中,无向边使用两条有向边表示,这里只需要改一下,添加/删除关系的时候只需要操作一条边即可。
忽略边:在读入边的时候,如果存在轨道物体向中心点的边则不操作,然后将其他所有的边加入,这里当然也包括了外层轨道到内层轨道的边,但是这里我们保留它,因为从实际应用角度出发,虽然一条边是从外层轨道到内层轨道的,但是在添加/删除关系之后这条边也可能变成内到外的边。
如何忽略?这里我们求出所有点到中心点的距离,根据距离即可判断内外(也可以求出所在的轨道-更简),每次更改关系结构之后需要重新求一遍距离,所以将求距离操作设计在adjustFriendsLocation中。
忽略影响:修改visualizeContentPanel,不显示外到内的边。修改求扩散度的操作,忽略所有外到内的边。但是如果两点之间是外到内的边,两者依然是相连的关系,这点在面板上的删除边功能上有所体现。
图7.修改之后的SocialNetworkOrbit(解释:在删除关系中有FrankLee->DavidChen的一条边,但是因为这条边是由外到内的所以在轨道系统图上被忽略了)
我是迷人的小尾巴
以下外链,利益相关,欢迎浏览ε≡٩(๑>₃<)۶ :
济南江鹏工贸有限公司(山东济南机械加工),济南彤昌机械科技有限公司(山东济南机械加工)