欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

软件构造lab3

程序员文章站 2024-02-09 17:16:52
...

目录

1 实验目标概述 1
2 实验环境配置 1
3 实验过程 1
3.1 待开发的三个应用场景 1
3.2 基于语法的图数据输入 1
3.3 面向复用的设计:CircularOrbit<L,E> 1
3.4 面向复用的设计:Track 2
3.5 面向复用的设计:L 2
3.6 面向复用的设计:PhysicalObject 2
3.7 可复用API设计 2
3.8 图的可视化:第三方API的复用 2
3.9 设计模式应用 2
3.10 应用设计与开发 2
3.10.1 TrackGame 2
3.10.2 StellarSystem 2
3.10.3 AtomStructure 2
3.10.4 PersonalAppEcosystem 2
3.10.5 SocialNetworkCircle 2
3.11 应对应用面临的新变化 2
3.11.1 TrackGame 3
3.11.2 StellarSystem 3
3.11.3 AtomStructure 3
3.11.4 PersonalAppEcosystem 3
3.11.5 SocialNetworkCircle 3
3.12 Git仓库结构 3
4 实验进度记录 3
5 实验过程中遇到的困难与解决途径 3
6 实验过程中收获的经验、教训、感想 4
6.1 实验过程中收获的经验和教训 4
6.2 针对以下方面的感受 4

1实验目标概述
根据实验手册简要撰写。
本次实验覆盖课程第 3、5、6 章的内容,目标是编写具有可复用性和可维护
性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的 OO 设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API 设计、API 复用
本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构
可视化、个人移动 App 生态系统、个人社交系统),学生不是直接针对五个应用
分别编程实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其
实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可
复用性)和更容易面向各种变化(可维护性)。

2实验环境配置
简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。
特别是要记录配置过程中遇到的问题和困难,以及如何解决的。
实验环境设置请参见 Lab-0 实验指南。本次无需额外配置

3实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1待开发的三个应用场景
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
2,行星运动模拟
3,原子结构模型
5,社交网络好友分布
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
共性:需要轨道系统中基本存在的对象,包括轨道、中心物体、轨道物体。其中物体都不考虑绝对位置。轨道都为圆形。
都需要完成的功能有:添加/删除轨道,在某一轨道上添加/删除物体,获得轨道系统的熵值,获得逻辑距离,比较两个同类型轨道系统的差异,检查轨道系统是否合法,可视化。
差异:StellarSystem每层只有一个物体,AtomStructure轨道物体都是值相同的对象,需要实现物体跃迁。SocialNetworkCircle中需要实现物体关系及对应操作,需要计算信息扩散度。
3.2基于语法的图数据输入
以下分别是三个应用的在输入处理中设计的正则表达式:
StellarSystem:
String a=“Stellar ::= <([a-zA-Z0-9]+),(.),(.)>”;
String b=“Planet ::= <([a-zA-Z0-9]+),([a-zA-Z0-9]+),([a-zA-Z0-9]+),(.),(.),(.),(.),(.*)>”;

AtomStructure:
String a=“ElementName\s*::=\s*([A-Z][a-z]?)”;
String b=“NumberOfElectron\s*::=\s*((??????:\d+\/\d+)|;)+)”;

SocialNetworkCircle:
String a = “CentralUser\s*::=\s* <([A-Za-z0-9]+),\s*(\d+),\s*([MF])>”;
String b = “Friend\s*::=\s*<([A-Za-z0-9]+),\s*(\d+),\s*([MF])>”;
String c = “SocialTie\s*::=\s*<([A-Za-z0-9]+),\s*([A-Za-z0-9]+),\s*(0(?:\.\d{1,3})?|1(?:\.0{1,3})?)>”;

对于在文件中读入的每一行,尝试用不同的pattern进行匹配并进行对应的处理(包括split),如果不能匹配则抛出运行时异常MyExp(自定义异常)。
其中SocialTie的正则表达式中用到了?:代表该括号是一个非捕获组,对于有多个括号的捕获情况,捕获顺序是从左到右,从外到内(嵌套)。
3.3面向复用的设计:CircularOrbit<L,E>
类的域:
private L cenL; //中心体
private Set a=new HashSet(); //中心体有关物体集合
private Map<Track, Set> b=new HashMap<Track, Set>(); //轨道及其上面的物体地图
private Map<E, Set> c=new HashMap<E, Set>(); //物体及其有关物体集合图

方法以及实现:public Set addTrack(Track aTrack); //增加一条轨道

public Set<Track> removeTrack(Track aTrack);  //去除一条轨道

public L  addCentralPoint(L aCentralObject); //增加中心点物体

public Set<E>  TrackaddPhysicalObject(Track aTrack,E aPhysicalObject); //向特定轨道上增加一个物体(不考虑物理位置)

public Set<E>  addCentralPointandTrack(E aPhysicalObject); //增加中心点物体和一个轨道物体之间的关系

public Map<E,Set<E>>  addTrackandTrack(E aPhysicalObject,E bPhysicalObject); //增加两个轨道物体之间的关系

public double getObjectDistributionEntropy();  //获取轨道系统的熵值

public int getLogicalDistance(E e1,E e2) ;//使用BFS算法计算e1和e2之间的逻辑距离。

public Difference<L,E> getDifference(ConcreteCircularOrbit<L, E> that); //获得自身轨道系统与同类型轨道系统that之间的系统差异

public Boolean checkOrbitAvailable();//检查系统是否合法,直接返回true交给具体应用系统进行重写。

public Iterator<E> iterator(); //返回iterator迭代器

public void transit (E object, Track t);  //将 object 从当前所在轨道迁移到轨道 t

public List<Track>  sortrack();   //轨道排序

public List<Set<E>>  sortE();  //物体集合按轨道排序

3.4面向复用的设计:Track
Immutable类。只有一个radius域。

方法:

getter,覆盖equals方法,Track使用Radius判断两个Track是否相等。
3.5面向复用的设计:L

Immutable对象类。
只有一个name域。

方法:getter,equals
3.6面向复用的设计:PhysicalObject
Immutable类
只有一个name域
方法:getter
3.7可复用API设计
计算轨道系统熵值。在ConcreteCircularOrbit中已经具体实现。
获取最短逻辑距离。在ConcreteCircularOrbit中已经具体实现。
获取物理距离:只有第二个应用需要实现,在stellarsystem中实现.
计算两个多轨道系统之间的差异:
在ConcreteCircularOrbit中我们将两个对应的轨道物体集合添加到Difference对象中。下面声明Difference的类设计。

每一对比较的轨道,各自形成集合且只保留各自轨道上独有的轨道物体(去除交集),通过一个集合和自身构造trackDifference对象,一个轨道系统的Difference由多个trackDifference构成。在trackDifference中提供toString方法将差异转化为字串,需要注意的是,如果两个集合都为空则说明两轨道上物体完全相同,这时候不输出“物体差异”。

3.8图的可视化:第三方API的复用
3.9设计模式应用
请分小节介绍每种设计模式在你的ADT和应用设计中的具体应用。
高级类
Track,PhysicalObject等对象使用静态工厂方法实现,在类中设计getInstance方法获得对象。
对于ConcreteCircularOrbit的构造使用builder设计模式,设计抽象类ConcreteCircularOrbitBuilder,包括buildTrack,buildeObjects,buildRelation,通过传入的参数添加轨道系统组成。
每个具体应用类的Builder继承自ConcreteCircularOrbitBuilder,覆盖createConcreteCircularOrbit方法分别创建对应的轨道系统对象。

3)Iterator设计模式。设计MyIterator类,构造方法中传入轨道系统的PhysicalObjectMap(保护),首先按照轨道排序,之后按照轨道物体位置排序(因为不考虑轨道物体绝对位置,所以不予实现),在其中添加一个迭代下标,hashNext判断下标是否越界,next移动下标后返回值。

4)façade设计模式,实现API类。

StellarSystem
实现strategy设计模式。

设计接口类,分别实现具体策略类,简单编排SimpleStrategy,随即编排RandomStrategy,按bestscore排序编排SortedScoreStrategy。具体类中实现assign函数。

AtomStructure
实现Memento设计模式管理电子跃迁的状态。
设计ElectronTransitMemento类,保存电子轨道跃迁信息,分别保存跃迁电子electron,源轨道fromTrack,目标轨道toTrack。
设计ElectronTransitCareTaker类,负责保存所有的动作列表,回退历史信息(返回删除点之后的所有操作列表)。回退动作先从CareTaker类中获得删除点之后的所有历史信息,然后传入轨道系统中反方向执行操作。

SocialNetworkCircle
不需要实现设计模式
3.10应用设计与开发
利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
3.10.StellarSystem
功能:给定初始时刻(读入文件时)各行星的位置,
计算输出 t 时刻各行星的位置;功能 2:计算恒星与某颗行星之间、两
颗行星之间的物理距离;

判断合法性:按要求实现

3.10.1AtomStructure
功能:模拟电子跃迁。调用ConcreteCircularOrbit中实现的transit函数即可。
判断合法性:无。

3.10.2SocialNetworkCircle
功能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即可。
3.11应对应用面临的新变化
以下各小节,只需保留和完成你所选定的应用即可。
3.11.1StellarSystem
画图时改变一下计算策略即可
3.11.2AtomStructure
原子核表达为多个质子和多个中子的组合:设计中子质子类,更改AtomCore,添加中子质子列表。修改AtomCore,覆盖drawGraphics方法,改一下AtomCore的显示字符串为多少个中子质子的组合。
3.11.3SocialNetworkCircle
为关系增加方向性:在原来的实现中,无向边使用两条有向边表示,这里只需要改一下,添加/删除关系的时候只需要操作一条边即可。

忽略边:在读入边的时候,如果存在轨道物体向中心点的边则不操作,然后将其他所有的边加入,这里当然也包括了外层轨道到内层轨道的边,但是这里我们保留它,因为从实际应用角度出发,虽然一条边是从外层轨道到内层轨道的,但是在添加/删除关系之后这条边也可能变成内到外的边。

如何忽略?这里我们求出所有点到中心点的距离,根据距离即可判断内外(也可以求出所在的轨道-更简),每次更改关系结构之后需要重新求一遍距离,所以将求距离操作设计在adjustFriendsLocation中。

忽略影响:修改visualizeContentPanel,不显示外到内的边。修改求扩散度的操作,忽略所有外到内的边。但是如果两点之间是外到内的边,两者依然是相连的关系,这点在面板上的删除边功能上有所体现。
3.12Git仓库结构
请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。