软件构造 Lab3

实验目的:
本次实验覆盖课程第 3、5、6 章的内容,目标是编写具有可复用性和可维护 性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API 设计、API 复用

本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构 可视化、个人移动 App 生态系统、个人社交系统),学生不是直接针对五个应用 分别编程实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其 实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可复用性)和更容易面向各种变化(可维护性)

需要用到的知识: JAVA文件读写、正则表达式、第三方API复用、设计模式应用。

实验任务:

待开发的三个应用场景
TrackGame
AtomStructure
SocialNetworkCircle

基于语法的图数据输入
基于语法的图数据输入,这部分是要使用正则表达式进行文件内容的读取。
三个场景的正则表达式如下:
TrackGame:
在这里插入图片描述
AtomStructure:
在这里插入图片描述
SocialNetworkCircle:
在这里插入图片描述
以SocialNetworkCircle为例:
在这里插入图片描述
首先定义正则表达式。
软件构造 Lab3_第1张图片
之后按行读取文件内容,分别用以上正则表达式进行匹配。
匹配到相应信息,就创建相应的对象,加入程序的数据集中。

面向复用的设计:CircularOrbit
CircularOrbit使用泛型编程,作为其他子类的接口。
其中定义了如下函数:

/**
	 * Use: 创建一个空的 CircularOrbit对象.
	 * 
	 * @param L为中心物体类,E为轨道物体类。
	 * @return 返回一个空的 CircularOrbit对象。
	 */
	public static  CircularOrbit empty() {
    	return null;
    }
	
	
	/**
	 * Use: 添加一条轨道。
	 * 
	 * @param 输入一条轨道。
	 * @return 添加是否成功,若已存在就返回失败,否则成功。
	 */
	public boolean AddTrack(Track track);
	
	/**
	 * Use: 删除一条轨道。
	 * 
	 * @param 输入一条轨道。
	 * @return 删除是否成功。
	 */
	public boolean DeleteTrack(Track track);
	
	/**
	 * Use: 添加一个中心物体。
	 * 
	 * @param 中心物体。
	 */
	public void AddCentralObject(L centralObject);
	
	/**
	 * Use: 在特定轨道上增加一个物体。
	 * 
	 * @param (1)轨道, (2)物体。	要求轨道和物体已经存在。
	 * @return 添加是否成功。
	 */
	public boolean AddPhysicalObjectToTrack(Track track, E physicalObject);
	
	/**
	 * Use: 增加中心点物体和一个轨道物体之间的关系
	 * 
	 * @param (1)轨道物体。	要求中心点物体和轨道物体已经存在。
	 * @return 无
	 */
	public void AddRelation_CentralToPhysical(E physicalObject, float intimacy);
	
	/**
	 * Use: 增加两个轨道物体之间的关系
	 * 
	 * @param (1)轨道物体1,(2)轨道物体2。	要求轨道物体已经存在。
	 * @return 无
	 */
	public void AddRelation_PhysicalToPhysical(E physicalObject_1, E physicalObject_2,  float intimacy);
	
	/**
	 * Use: 从外部文件读取数据构造轨道系统对象
	 * 
	 * @param (1)文件地址。
	 * @return 无。
	 */
	public void readFile(String pathname);
	
	/**
	 * Use: 将 object 从当前所在轨道迁移到轨道 t
	 * 
	 * @param (1)轨道物体 (2)目标轨道。
	 * @return 无。
	 */
	public void transit (E object, Track t);
	
	/**
	 * Use: 将 object 从 当前位置移动到新的 sitha 角度所对应的位置
	 * 
	 * @param (1)轨道物体 (2)新的 sitha 角度。
	 * @return 无。
	 */
	public void move(E object, double sitha);
	
	/**
	 * Use: 将 object 从系统中移除
	 * 
	 * @param (1)轨道物体
	 * @return 无。
	 */
	public void remove(E object);

函数作用已写在相应注释中。

面向复用的设计:Track

Track,轨道类。
这个类下没有太多属性,因为三个应用中都不存在半径长度的概念,因此在Track中只有轨道编号的属性。为Immutable不可改变类型。软件构造 Lab3_第2张图片

面向复用的设计:L
面向复用设计。L为中心物体类。
中心物体同样也没有太多属性,除了TrackGame外,SocialNetworkCircle和AtomStructure两个应用的中心物体的共同属性只有name一个,因此抽象出来,成为父类。
软件构造 Lab3_第3张图片

面向复用的设计:PhysicalObject
面向复用设计。PhysicalObject为轨道物体类。
与中心物体的情况类似,三个应用中,轨道物体分别为:运动员、电子和朋友。
它们的共同属性只有name一个,因此抽象出来,成为父类。
软件构造 Lab3_第4张图片

可复用API设计

可复用API写在CircularOrbitAPIs里,有四个功能:
计算熵值、计算逻辑距离、计算物理距离、返回不同。
这里因为三个应用中不存在物理距离,因此直接返回-1;
计算逻辑距离只对SocialNetworkCircle有效,因此只有在是SocialNetworkCircle才被调用。软件构造 Lab3_第5张图片
查询不同时,有一个类Difference:软件构造 Lab3_第6张图片
它内部记录了轨道数的不同、各轨道上物体数的不同和各轨道物体的不同。

图的可视化:第三方API的复用
可视化部分写在CircularOrbitHelper.java文件里。
这部分主要实现了图的可视化。
首先CircularOrbitHelper继承了JFrame类,有常量窗口图的位置。
软件构造 Lab3_第7张图片
这个类中最关键的部分是visualize函数。
它负责生成窗口和面板。输入为一个CircularOrbit,根据其类型来生成对应的图。
如下:
软件构造 Lab3_第8张图片
之后有一个Scean类,它继承了面板Panel类。负责图的绘制。如下:
软件构造 Lab3_第9张图片
首先它获取到图位置信息常量,之后进行绘制。
如下,它判断了输入的图的类型,根据其类型的不同,以不同的方式绘制图。
软件构造 Lab3_第10张图片
最后的效果:
软件构造 Lab3_第11张图片

设计模式应用
factory method设计模式:
在这里插入图片描述
首先,有四个工厂负责各个类型的对象生成。
以PhysicalObject的factory为例:
软件构造 Lab3_第12张图片
这里我使用的是static factory的方式,根据输入参数的不同,来对应生成相应的PhysicalObject。

strategy设计模式:
软件构造 Lab3_第13张图片
在TrackGame中,使用strategy设计模式,根据输入要求的不同,使用相应的策略进行分组编排(随机/按分数)。

façade 设计模式:
将所有 API 放置在 helper 类 CircularOrbitAPIs 当中。
软件构造 Lab3_第14张图片

state 设计模式:
在这里插入图片描述
这里我使用一个Map来保存跃迁前的信息。
软件构造 Lab3_第15张图片
之后在每次跃迁之前,都对信息进行一次保存更新,这样就能保存下来电子的跃迁前状态,以便于以后的恢复。

你可能感兴趣的:(软件构造 Lab3)