软件构造实验三
本次实验覆盖课程第 3、5、6 章的内容,目标是编写具有可复用性和可维护 性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的 OO 设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API 设计、API 复用 本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构 可视化、个人移动 App 生态系统、个人社交系统),学生不是直接针对五个应用 分别编程实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其 实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可 复用性)和更容易面向各种变化(可维护性)
实验环境:
- 系统:windows10,JDK8
- ide:Eclipse IDE for Eclipse Committers 2018-12 (4.10.0)
- 版本管理:git
- 代码托管:Github
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/Lab3-1170300527.git
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
- Stellar System
- Atom Structure
- Social Network Circle
共性:
- 需要轨道系统中基本存在的对象,包括轨道、中心物体、轨道物体。其中物体都不考虑绝对位置。轨道都为圆形
- 都需要完成的功能有:添加/删除轨道,在某一轨道上添加/删除物体,获得轨道系统的熵值,获得逻辑距离,比较两个同类型轨道系统的差异,检查轨道系统是否合法,可视化
差异:
- 包含的结构不同,行星需要考虑其绝对位置,并且位置会根据时间变化,原子与社交网络则无需考虑
- 具体实现的功能要求也存在差异
根据给出的输入结构写出正则表达式进行匹配,每读入一行将其分别进行匹配,并进行处理
行星系统:
原子系统:
社交网络:
-
- 面向复用的设计:CircularOrbit<L,E>
设计为接口,提取系统中的共有方法
方法 |
作用 |
public CircularOrbit<L,E> concreteCircularOrbit (); |
创建一个空的 CircularOrbit 对象 |
public void setOrbit(Track t); |
增加一条轨道 |
public void removeOrbit(Track t); |
去除一条轨道 |
public void setCenter(L center); |
增加中心点物体 |
public void setObject(E object, Track t); |
向特定轨道上增加一个物体(不考虑物理位置) |
public void readFile(String file); |
从外部文件读取数据构造轨道系统对象 |
public void transit (E object, Track t); |
将 object 从当前所在轨道迁移到轨道 t |
public void move(E object, double sitha); |
将 object 从 当前位置移动到新的 sitha 角度所对应的位置
|
-
- 面向复用的设计:Track
包含两个属性,编号及半径
在行星系统中track按半径由小到大排列
在原子模型及社交网络中由于不存在半径大小,故编号及半径都设为轨道的层数
重写hashcode及equals方法,只要半径相同及认为相等
L及中心物体,恒星,原子核,人都有名称的属性,故其父类提取出name属性
恒星,原子核,人全部继承于CentralObject并增加自己的属性,恒星还有重量和半径均为double类型的属性,电子只有名字一个属性直接继承即可,人还有int的年龄和性别,由于性别只有两种,故以boolean类型代替
-
- 面向复用的设计:PhysicalObject
physicalObject及为多轨道系统中的E,行星,电子分别继承自它,社交网络中的人使用CentralObject中的person即可,由于电子属性较少,只设置了一个name属性代表其所在轨道层数。physicalObject为其共有父类也只有一个name属性,行星属性较多,继承后添加其独有的属性。
并重写了hashcode于与equals方法
-
- 可复用API设计
- 计算轨道系统熵值。
- 获取最短逻辑距离。行星之间无逻辑距离,电子逻辑距离为电子层数的差,社交网络逻辑距离为两人之间路径的长度
- 获取物理距离:只在行星系统中实现
- 计算两个多轨道系统之间的差异:行星轨道的差异以轨道编号区分而未使用轨道的实际半径,如使用实际半径,每一条轨道都将不同,行星系统中基本无法找到相同轨道半径的行星
CircularOrbitAPIs设计为接口,由ConcreteCircularOrbit继承并在三个系统中分别实习,这样可以根据系统的不同,将CircularOrbit安全的强转为其子类
-
- 图的可视化:第三方API的复用
可视化工具使用的是Swing
- 行星轨道系统
本系统为考虑行星的实际半径,其差异太大,将无法显示完全系统的轨道,行星运行使用角速度,虽然外层行星运动较快但角速度较小,故运动时基本看不到外层行星运动,即使将运动速度设置为int类型的最大值最外层也基本不动,但将其position输出后可以看出角度还是有很小的变化的。
运动时采用多线程,否则将导致屏幕不断闪烁,每执行一次使用getNewPositon方法得出新的position并用repaint重绘制
- 电子轨道系统
根据传入的map知道其电子层数及各层电子数即可绘制
- 社交网络系统
基本的绘制与电子的类似,但还需要加上有关系的两人间的连线,这就要麻烦很多,在画轨道时设置map,以每个人的下标记录每个人的位置。之后再遍历关系的邻接矩阵edge,edge中两人亲密度不为0时添加线,不过要注意,亲密度不为0也可能不在轨道系统中,还要判断。
设计之初打算把物体,轨道,连线分别设计成不同的panel,之后根据系统的不同之间再jframe中之间分别add不同的panel就可以了也比较简单复用性也比较好,但应用时会遇到只显示最后一个panel,查了好久还是失败了。最后采用了分别绘制的方法
行星轨道运动时需要使用多线程操作,否则将发生屏幕不断闪烁的问题
- 三个系统采用工厂的设计模式,根据需要的不同返回相应的子类,并可以进行安全的强转
- 对电子操作后采用moment模式,用moment存储相应的状态记录轨道及电子,Storage存储moment,每次对电子操作后创建一个新的moment进行存储,,可以根据操作的编号进行恢复
利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
完成了需求中的全部要求
1.GUI可视化展示轨道
2.删除轨道及行星
3.增加行星
4.输出t时刻后行星位置
5.计算两行星间距离
6.计算熵值 CircularOrbitAPIs中实现
7.得到两系统中不同 CircularOrbitAPIs中实现
由于行星系统中轨道与行星是一对一的,所以将删除轨道与删除行星结合在一起,只需输入轨道半径即可删除
设立了两个map,分别存储轨道和当前位置,position是可变的,其中包含角度,速度,方向,半径,这样通过position和时间即可计算出指定时间后的位置,也可通过行星之间找到map,行星和轨道都按照轨道半径的大小进行排序,每次增删时都进行了重新排序。
合法性检查:按照要求,每次更改操作后均进行check
完成了需求中的全部要求
1.GUI可视化展示轨道
2.删除轨道 指定轨道编号
3.删除电子 指定轨道及电子数量
4.模拟电子跃迁 由指定旧轨道跃迁指点电子数到新轨道
5.新增轨道 轨道不能独立电子存在,故新增轨道时只需指定新轨道电子数量,自动生成下一轨道
6.删除电子 指定轨道及电子数目
7.计算系统熵值 指定轨道系统
判断合法性:无
完成了需求中的全部要求
1.GUI可视化展示轨道
2.增加一个人
3.删除一个人
4.增加一个关系
5.删除一个关系
6.获取信息扩散度
7.获取两人的逻辑距离 通过关系邻接矩阵的广搜
8.计算系统熵值 CircularOrbitAPIs中实现
通过输入的关系建立邻接矩阵,lab1与lab2均有涉及,通过对邻接矩阵的处理转化为多轨道系统,因为人数都是可变的,故都采用list的存储方式
注意:信息扩散度再计算时两人之间可能存在多条路径,亲密度不相同故首先通过广搜计算所有与之相连的人,再通过深搜计算两人间所有的路径,亲密度为路径上亲密度乘积的最大值,当亲密度大于0.01时视为二者存在联系
合法性:使用邻接矩阵的广搜,搜索到的逻辑距离即为最短的路径,满足条件
以下各小节,只需保留和完成你所选定的应用即可。
创建新的轨道及position属性,修改计算位置的函数
以恒定角速度变化,图为示例,难点在于计算位置
更改计算行星距离的公式,分别计算两点的坐标,然后计算距离
改变原子核类,增加质子及中子数目
修改正则表达式,在原子名称后面输入质子及中子数以/隔开如:ElementName ::= Rb 37/48
由于建立轨道时是由邻接矩阵转化而来,只需将邻接矩阵建立时改变赋值条件即可,后续改变不大,按要求改变绘图原则。
当画直线时遍历判断两人所处的轨道编号,只能从靠近中心的轨道向边缘轨道画图
本次实验覆盖课程第 3、5、6 章的内容,目标是编写具有可复用性和可维护 性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的 OO 设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API 设计、API 复用 本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构 可视化、个人移动 App 生态系统、个人社交系统),学生不是直接针对五个应用 分别编程实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其 实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可 复用性)和更容易面向各种变化(可维护性)
实验环境:
- 系统:windows10,JDK8
- ide:Eclipse IDE for Eclipse Committers 2018-12 (4.10.0)
- 版本管理:git
- 代码托管:Github
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/Lab3-1170300527.git
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
- Stellar System
- Atom Structure
- Social Network Circle
共性:
- 需要轨道系统中基本存在的对象,包括轨道、中心物体、轨道物体。其中物体都不考虑绝对位置。轨道都为圆形
- 都需要完成的功能有:添加/删除轨道,在某一轨道上添加/删除物体,获得轨道系统的熵值,获得逻辑距离,比较两个同类型轨道系统的差异,检查轨道系统是否合法,可视化
差异:
- 包含的结构不同,行星需要考虑其绝对位置,并且位置会根据时间变化,原子与社交网络则无需考虑
- 具体实现的功能要求也存在差异
根据给出的输入结构写出正则表达式进行匹配,每读入一行将其分别进行匹配,并进行处理
行星系统:
原子系统:
社交网络:
-
- 面向复用的设计:CircularOrbit<L,E>
设计为接口,提取系统中的共有方法
方法 |
作用 |
public CircularOrbit<L,E> concreteCircularOrbit (); |
创建一个空的 CircularOrbit 对象 |
public void setOrbit(Track t); |
增加一条轨道 |
public void removeOrbit(Track t); |
去除一条轨道 |
public void setCenter(L center); |
增加中心点物体 |
public void setObject(E object, Track t); |
向特定轨道上增加一个物体(不考虑物理位置) |
public void readFile(String file); |
从外部文件读取数据构造轨道系统对象 |
public void transit (E object, Track t); |
将 object 从当前所在轨道迁移到轨道 t |
public void move(E object, double sitha); |
将 object 从 当前位置移动到新的 sitha 角度所对应的位置
|
-
- 面向复用的设计:Track
包含两个属性,编号及半径
在行星系统中track按半径由小到大排列
在原子模型及社交网络中由于不存在半径大小,故编号及半径都设为轨道的层数
重写hashcode及equals方法,只要半径相同及认为相等
L及中心物体,恒星,原子核,人都有名称的属性,故其父类提取出name属性
恒星,原子核,人全部继承于CentralObject并增加自己的属性,恒星还有重量和半径均为double类型的属性,电子只有名字一个属性直接继承即可,人还有int的年龄和性别,由于性别只有两种,故以boolean类型代替
-
- 面向复用的设计:PhysicalObject
physicalObject及为多轨道系统中的E,行星,电子分别继承自它,社交网络中的人使用CentralObject中的person即可,由于电子属性较少,只设置了一个name属性代表其所在轨道层数。physicalObject为其共有父类也只有一个name属性,行星属性较多,继承后添加其独有的属性。
并重写了hashcode于与equals方法
-
- 可复用API设计
- 计算轨道系统熵值。
- 获取最短逻辑距离。行星之间无逻辑距离,电子逻辑距离为电子层数的差,社交网络逻辑距离为两人之间路径的长度
- 获取物理距离:只在行星系统中实现
- 计算两个多轨道系统之间的差异:行星轨道的差异以轨道编号区分而未使用轨道的实际半径,如使用实际半径,每一条轨道都将不同,行星系统中基本无法找到相同轨道半径的行星
CircularOrbitAPIs设计为接口,由ConcreteCircularOrbit继承并在三个系统中分别实习,这样可以根据系统的不同,将CircularOrbit安全的强转为其子类
-
- 图的可视化:第三方API的复用
可视化工具使用的是Swing
- 行星轨道系统
本系统为考虑行星的实际半径,其差异太大,将无法显示完全系统的轨道,行星运行使用角速度,虽然外层行星运动较快但角速度较小,故运动时基本看不到外层行星运动,即使将运动速度设置为int类型的最大值最外层也基本不动,但将其position输出后可以看出角度还是有很小的变化的。
运动时采用多线程,否则将导致屏幕不断闪烁,每执行一次使用getNewPositon方法得出新的position并用repaint重绘制
- 电子轨道系统
根据传入的map知道其电子层数及各层电子数即可绘制
- 社交网络系统
基本的绘制与电子的类似,但还需要加上有关系的两人间的连线,这就要麻烦很多,在画轨道时设置map,以每个人的下标记录每个人的位置。之后再遍历关系的邻接矩阵edge,edge中两人亲密度不为0时添加线,不过要注意,亲密度不为0也可能不在轨道系统中,还要判断。
设计之初打算把物体,轨道,连线分别设计成不同的panel,之后根据系统的不同之间再jframe中之间分别add不同的panel就可以了也比较简单复用性也比较好,但应用时会遇到只显示最后一个panel,查了好久还是失败了。最后采用了分别绘制的方法
行星轨道运动时需要使用多线程操作,否则将发生屏幕不断闪烁的问题
- 三个系统采用工厂的设计模式,根据需要的不同返回相应的子类,并可以进行安全的强转
- 对电子操作后采用moment模式,用moment存储相应的状态记录轨道及电子,Storage存储moment,每次对电子操作后创建一个新的moment进行存储,,可以根据操作的编号进行恢复
利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
完成了需求中的全部要求
1.GUI可视化展示轨道
2.删除轨道及行星
3.增加行星
4.输出t时刻后行星位置
5.计算两行星间距离
6.计算熵值 CircularOrbitAPIs中实现
7.得到两系统中不同 CircularOrbitAPIs中实现
由于行星系统中轨道与行星是一对一的,所以将删除轨道与删除行星结合在一起,只需输入轨道半径即可删除
设立了两个map,分别存储轨道和当前位置,position是可变的,其中包含角度,速度,方向,半径,这样通过position和时间即可计算出指定时间后的位置,也可通过行星之间找到map,行星和轨道都按照轨道半径的大小进行排序,每次增删时都进行了重新排序。
合法性检查:按照要求,每次更改操作后均进行check
完成了需求中的全部要求
1.GUI可视化展示轨道
2.删除轨道 指定轨道编号
3.删除电子 指定轨道及电子数量
4.模拟电子跃迁 由指定旧轨道跃迁指点电子数到新轨道
5.新增轨道 轨道不能独立电子存在,故新增轨道时只需指定新轨道电子数量,自动生成下一轨道
6.删除电子 指定轨道及电子数目
7.计算系统熵值 指定轨道系统
判断合法性:无
完成了需求中的全部要求
1.GUI可视化展示轨道
2.增加一个人
3.删除一个人
4.增加一个关系
5.删除一个关系
6.获取信息扩散度
7.获取两人的逻辑距离 通过关系邻接矩阵的广搜
8.计算系统熵值 CircularOrbitAPIs中实现
通过输入的关系建立邻接矩阵,lab1与lab2均有涉及,通过对邻接矩阵的处理转化为多轨道系统,因为人数都是可变的,故都采用list的存储方式
注意:信息扩散度再计算时两人之间可能存在多条路径,亲密度不相同故首先通过广搜计算所有与之相连的人,再通过深搜计算两人间所有的路径,亲密度为路径上亲密度乘积的最大值,当亲密度大于0.01时视为二者存在联系
合法性:使用邻接矩阵的广搜,搜索到的逻辑距离即为最短的路径,满足条件
以下各小节,只需保留和完成你所选定的应用即可。
创建新的轨道及position属性,修改计算位置的函数
以恒定角速度变化,图为示例,难点在于计算位置
更改计算行星距离的公式,分别计算两点的坐标,然后计算距离
改变原子核类,增加质子及中子数目
修改正则表达式,在原子名称后面输入质子及中子数以/隔开如:ElementName ::= Rb 37/48
由于建立轨道时是由邻接矩阵转化而来,只需将邻接矩阵建立时改变赋值条件即可,后续改变不大,按要求改变绘图原则。
当画直线时遍历判断两人所处的轨道编号,只能从靠近中心的轨道向边缘轨道画图