3.1 待开发的三个应用场景
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
行星系统
原子系统
社交网络
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
他们都具有轨道,中心物体,轨道物体等属性,但是各自具体的属性不同,行星系统上物体有实际物理位置,其他两个系统无,行星系统每个轨道只有一个物体,其他两个系统有多个,社交网络有关系概念,还有亲密度概念。
3.2 基于语法的图数据输入
读入文件,根据文件的结构运用正则表达式来实现系统
3.3 面向复用的设计:CircularOrbit<L,E>
设计接口,提出公用方法//返回一个空系统
public ConcreteCircularOrbit<L, E> empty();
/*
* 加入一个轨道
*
*
*/
public void addTrack(Track a);
/*
*
* 删除指定轨道
*
*/
public boolean removeTrack(Track a);
// TODO 自动生成的方法存根
/*
* 设置中心点并加入
*
*
*
*/
public void CentralPoint(L a);
/*
* 在特定的轨道加入物理对象
*
*/
public void addPhyobjectinTrack(E object , Track a);
/*
* 增加中心点和一外部点的关系
*
*/
public void addrelationwithcentral( E b) ;
/*
* 增加两个外部点的关系
*/
public void addrelationwithTrackObject(E a, E b) ;
/*
* 读文件
*/
/*
*移动点到特定轨道
*/
public void transit(E object, Track t);
并实际实现这个系统,
然后具体系统继承这个系统,在根据具体系统的不同细节修改,增添新的属性。
3.4 面向复用的设计:Track
轨道,
final private double distance;
final private int number;
这里只提出了轨道的距离和编号作为所以系统轨道的公有属性。
3.5 面向复用的设计:L
中心物体
Final private String name ;
只提出了名字作为所以物体的公有属性,其他属性根据具体应用加入。。
3.6 面向复用的设计:PhysicalObject
final private String name ;
protected final double distance;
只提出了距离和名字作为轨道上物体的公有属性。
3.7 可复用API设计public double getObjectDistributionEntropy(CircularOrbit c)
针对所有系统的计算熵值的方法。
这里采用 作为计算熵的公式,定义p(x)为该轨道上物体数/总物体数,得到的结果,恰好满足分布越均匀,熵值越高的定义。
public double getPhysicalDistance (CircularOrbit c, E e1, E e2)
计算物理距离的公有方法,显然,只有行星系统有物理距离的概念,这里若是行星系统,则直接调用行星系统中写过的计算物理距离方法,否则,直接返回并输出无物理距离概念。
public int getLogicalDistance (ConcreteCircularOrbit c, E e1, E e2)
计算逻辑距离的公有方法,这里采用弗洛伊德算法来求最短距离在关系网络里来计算逻辑距离
public Difference getDifference(ConcreteCircularOrbit c1, ConcreteCircularOrbit c2)
得到两个系统的不同的公有方法
设计difference类
int tracknumberdifference;//记录两个系统轨道数不同
ArrayList objectnumberdifference = new ArrayList<>();//记录两个系统每个轨道上物体数差异
ArrayList<Set>firstobjectdifference = new ArrayList<>();//记录第一个系统某轨道上与另一系统该轨道上物体的不同。
ArrayList<Set>secondjectdifference = new ArrayList<>();记录第二个系统某轨道上与第一个系统该轨道上物体的不同。
该公有方法得到两个系统的差异,在计算轨道上物体数量和具体物体差异时,需要判断轨道上物体数量大小。在将具体不同加入到相应集合。
3.8 图的可视化:第三方API的复用
设计了public static void visualize(CircularOrbit c)的静态方法,这里先判断该系统的类型,在根据具体类型生成相应可视化。
3.9 设计模式应用
高级类 Track,PhysicalObject 等对象使用静态工厂方法实现,在类中设计 getInstance 方法获得对象。 对于 ConcreteCircularOrbit 的构造使用 builder 设计模式,设计抽象 类 ConcreteCircularOrbitBuilder,包括 buildTrack,buildeObjects, buildRelation,通过传入的参数添加轨道系统组成。 每个具体应用类的 Builder 继承自 ConcreteCircularOrbitBuilder,覆 盖 createConcreteCircularOrbit 方法分别创建对应的轨道系统对象。应用设计与开发
利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
3.9.1 TrackGame
3.9.2 StellarSystem
-
设计具体的星球及恒星类
分别继承physicalobjetc类和centralobject类,并为其加上各自该有的属性
如行星有名称,形态,颜色,行星半径,轨道半径,公转 速度,公转方向,初始位置的角度,
恒星有名称,半径,质量;
2.,实现该系统特有的方法
public Position getPosition(double t,Planet a)
计算星球位置,需要时间t
public double centraldistance(Planet a)
计算恒星与行星距离,直接得到行星距离即可
public double planetdistance(Planet a,Planet b,double t)
计算行星间距离,需要用余弦定理
3.9.3 AtomStructure
直接继承ConcreteCircularOrbit,所有需要的方法已经实现,只需要加入读文件功能即可;
3.9.4 PersonalAppEcosystem
3.9.5 SocialNetworkCircle
3.10 应对应用面临的新变化
3.11.1 StellarSystem 画图时改变一下计算策略即可
3.11.2 AtomStructure 原子核表达为多个质子和多个中子的组合:设计中子质子类,更改 AtomCore,添加中子质 子列表。修改 AtomCore,覆盖 drawGraphics 方法,改一下 AtomCore 的显示字符串为多少 个中子质子的组合。 软件构造课程实验报告 实验 3:面向复用和可维护性的软件构造
3.11.3 SocialNetworkCircle 为关系增加方向性:在原来的实现中,无向边使用两条有向边表示,这里只需要改一下,添 加/删除关系的时候只需要操作一条边即可。 忽略边:在读入边的时候,如果存在轨道物体向中心点的边则不操作,然后将其他所有的边 加入,这里当然也包括了外层轨道到内层轨道的边,但是这里我们保留它,因为从实际应用 角度出发,虽然一条边是从外层轨道到内层轨道的,但是在添加/删除关系之后这条边也可 能变成内到外的边。 如何忽略?这里我们求出所有点到中心点的距离,根据距离即可判断内外(也可以求出所在 的轨道-更简),每次更改关系结构之后需要重新求一遍距离,所以将求距离操作设计在 adjustFriendsLocation 中。 忽略影响:修改 visualizeContentPanel,不显示外到内的边。修改求扩散度的操作,忽略所 有外到内的边。但是如果两点之间是外到内的边,两者依然是相连的关系,这点在面板上的 删除边功能上有所体现。