Lab3 Software Construction requirement and spec

0 写在之前

这次实验工作量很大(其实也没多少),但是如果把所有工作都放在五一小长假来完成,就会显得非常非常多。
这次实验的得失:继续lab2中p3的面向对象编程,只不过这次不是直接面向应用,而是从应用中先提取出一套ADT,然后通过继承和委托的方式实现三个应用,全部框架都需要自己搭建,构思。
学习的正则表达式的使用:但是还是有很大差别:我的正则表达式最初能成功将txt文件读入,但是没办法细化识别,比如StellarSystem中轨道半径超过100000,需要使用科学计数法等等,但是别人的可以。正则表达式会套用和会使用是两码事,还需要提高。
理解了API:我将所有的功能都放在ConcreteCircularOrbit中实现,所以觉得API就是没用的空壳,但是后来发现不是所有的ConcreteCircularOrbit都需要暴露给Client,只需要将Client在spec写明的条件暴露给他即可,其他的类可以作为内部功能类隐藏起来。
这次代码能够运行,但是远远谈不上美丽优雅,下次需要注意。(后续更新)

1 实验目标概述

目标:编写具有可复用性和可维护性的软件,主要使用以下软件构造技术:
子类型、泛型、多态、重写、重载
继承、代理、组合
常见的OO设计模式
语法驱动的编程、 正则表达式
基于状态的编程
API设计、API复用

2 实验环境配置

本次实验环境配置没有遇到问题,刚开始需要GUI的时候从eclipse market中下载了window插件,但是后来发现只需要导入swing库即可。
在这里给出你的GitHub Lab3仓库的URL地址(Lab3-学号)。
https://github.com/ComputerScienceHIT/Lab3-1170300909

3 实验过程

请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1 待开发的三个应用场景

首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
 StellarSystem
 AtomStructure
 SocialNetwork
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
共性: 他们都是能以轨道系统的形式表现出来,由三部分组成:
继承自ConcreteCircularOrbit的轨道类
继承自CentralObject 的中心物体类
继承自PhyscialObject的轨道物体类
不同:对于每个应用,每个类的成员变量可能不同,涉及到具体的操作也会有不同,比如SocialNetWork需要根据人物关系远近时刻调整半径和轨道。而StellarSystem 只需要根据文件输入重新为轨道排序输出即可。

3.2 基于语法的图数据输入

使用正则表达式对输入进行过滤和抓取:

设计好正则表达式后利用Matcher类对合法输入进行捕获:

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

Fields 成员变量:

Method
addTrack(Track track) 添加新轨道
removeTrack(Track track) 删除轨道
setCenter(L object) 设定中心物体
addrelationCentertoP(E target, double weight) 在轨道物体和中心物体之间添加关系,权值为weight
addphysicalObjectoTrack(E object, Track track) 在轨道上添加物体
addrelationPtoP(E source, E target, double weight) 在两个轨道物体之间添加关系,权值为weight
sortrackByradius() 将轨道按照升序排列
drawCircularOrbit(String type) GUI
getPhysicalObjectList() 获得轨道物体列表
containPhyscialObject(String label) 判断轨道物体是否已存在
deletePhysicalObject(String label) 从列表中删除轨道物体
getTrackofPhysicalObject(E object) 获得轨道物体的轨道
getTrackList() 获得轨道列表
getObjectonTrack(Track track) 获得指定轨道上物体列表
transit (String label, Track track) 将label为输入的物体E迁移到新轨道track上
getObjectDistributionEntropy(); 计算信息熵
getDifference(CircularOrbit<L, E> that) 获取轨道差异
getcenter() 获取中心物体

3.4 面向复用的设计:Track

Fields:

Methods:
getlabel() 获取label
getradius() 获取半径

3.5 面向复用的设计:L

Fields:

Methods:
getLabelString() 获取label

3.6 面向复用的设计:PhysicalObject

Fields:

Methods:
getLabel() 获取label
equals(Object object) 重写equals方法,比较两physicalObject相等只需要label相同即可

3.7 可复用API设计

功能全部在ConcreteCircularOrbit中实现,只需要在API中封装,将通用性的功能暴露给client即可。

3.8 图的可视化:第三方API的复用

具体实现位于ConcreteCircularOrbit:

主要是构造一个JPanel,重写paint方法:

但是选择的三个应用可视化具有细微差别:例如socialNetWork的可视化需要画出关系连线,所以在继承CircularOrbit的SocialNetworkOrbit中重写了该方法:

3.9 设计模式应用

请分小节介绍每种设计模式在你的ADT和应用设计中的具体应用。

3.9.1 工厂设计模式:

尝试使用了工厂模式:在获取physicalObject的时候为了隐藏创建实例的方式,新建的PhysicalObjectFactory 类, 用静态工厂方法获取实例:

3.9.2 Builder设计模式:

设计抽象CircularOrbitBuilder类作为具体builder类的父类
Methods:
getConcreteCircularOrbit() { 返回构造完成的对象
abstract void createCircularOrbit(); 抽象方法,实现时创建具体类型的Orbit
bulidPhysicalObjects(L centralObj, Map<Track, List> ObjectMap) 根据传入的centralObj和ObjectMap初始化concreteCircularOrbit中的关系Map
bulidTracks(List trackList) { 根据传入的trackList构造concreteCircularOrbit
在第三个应用socialnetWork中由于每次添加人物和关系时,会影响其他人的半径,故采用builder模式,每次调整后将新数据出给builder类重新建立一个新的Orbit:
socialnetWorkbuilder继承自CircularOrbitBuilder,需要添加传递人物关系的方法:

调用builder类:

3.9.3 Decorator设计模式

行星的卫星化可以使用decorator模式:

设置基类PlanetDecorator,新建Satellite类和SatellticPlanet类:
Satellite类:

SatellticPlanet类:

Methods
satelltic() 在具体子类中重写父类的方法
addSatellite(String label) 为行星添加卫星
removeSatellite(String label) 为行星删除卫星

3.9.4 facade设计模式

3.10 应用设计与开发

利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
在applications的main类中运行main即可:

输入1,2,3进入功能
End结束

3.10.1 StellarSystem

目录如下:

Planet类继承自PhysicalObject作为轨道物体,具有以下新增属性:

Methods:
caculatePosition(double t) 计算运动时间为t后行星在轨道上的位置
getrackRadius() 获取轨道半径
getInitAngle() 获取初始角度
toString() 重写tostring,输出Planet信息

Stellar类继承自CentralObject作为轨道物体,具有以下新增属性:

Methods:
toString() 重写tostring,输出Stellar信息

StellarSystem类继承自ConcreteCircularOrbit类:
Methods:
initByfile(String filename) 根据文件名读取文件,初始化轨道
caculatePosition(double t, String label) 计算t时刻位置
getPhyscialDistance(String label1,String label2) 计算两行星之间距离
menu() 菜单
drawCircularOrbit(String type) 由于行星有绝对位置,所以需要重写可视化方法
gomain() 主程序
运行演示:
读取文件:

增加行星(调用GUI查看是否添加)

删除行星:

删除轨道:

增加轨道:

计算信息熵:

计算t时刻行星位置:

计算行星物理距离:

3.10.2 AtomStructure

目录如下:

Electron类继承自PhysicalObject作为轨道物体
Nucleus类继承自CentralObject作为中心物体
AtomStructure类继承自ConcreteCircularOrbit类
Methods:
initByfile(String filename) 根据文件名读取文件,初始化轨道
menu() 菜单
gomain() 主程序

运行演示:
读取文件和可视化:

添加电子:

删除电子:

跃迁:

计算信息熵:

3.10.3 SocialNetworkCircle

目录如下:

Person类继承自PhysicalObject作为轨道物体
CentralUser类继承自CentralObject作为中心物体
SocialnetWorkOrbit类继承自ConcreteCircularOrbit类
SocialNetworkBuilder类继承自CircularOrbitBuilder类(在设计模式中已说明)

Socialnetwork类
Fields:

Methods:
initByfile(String filename) 根据文件名读取文件,初始化轨道
menu() 菜单
pprelationcontain(Person p1) 返回包含p1的关系中的另一半列表(即和p1有关系的列表)
buildOrbit() 将数据传给builder返回SocialnetworkOrbit
gomain() 主程序
演示:
读取文件和可视化:

删除朋友:

计算逻辑距离:

3.11 应对应用面临的新变化

以下各小节,只需保留和完成你所选定的应用即可。

3.11.1 StellarSystem

需要修改成椭圆轨道;只需要将轨道参数由半径换成长轴和短轴参数;
在StellarSystem中重写GUI方法,画出椭圆轨道即可:

3.11.2 AtomStructure

修改较为简单,只需要将在Nucleus中增加一个particle集合存放质子和中子即可
质子和中子的生成可以使用工厂方法:
重写tostring 方法:

新Particle类:(静态工厂方法得到不同实例)

3.11.3 SocialNetworkCircle

未完成

3.12 Git仓库结构

请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值