软件构造 Lab-3

一、先总结一下整个课程

这是一门实战性很强的课程,每个实验对于每个时期的我来说工作量都很大,而且很难,但最后的提升是很明显的。课程上王老师讲的非常非常好,拆的很细,深入浅出,而且不会有无聊的时候,可以感受到王老师造诣之高,只要每一步都跟上听进去了,绝对是受益匪浅。实验课徐老师也很负责很亲民,第一节课没赶上飞机给我们在线上解说,后续每个实验都进行了分析,而且每次实验都给我们延迟了ddl,这是我们十分感谢的。

我还是想吐槽一下,不过不是对这门课程,这门课程除了难度有点大(当然应该是我比较菜),是实用性非常强的一门课,王老师也在课上说“学会了这门课,就已经可以就业了”。想吐槽的是这学期课程和杂务非常的多,我单单期末考就有8门,从4月一路考到7月,压力很大,同时还要参加一些竞赛,我自己也有一点体育方面的训练和比赛,所以能够分出来的精力就很少了,这就导致了我在课后无法花费大量时间来消化吸收课程中的内容,也没办法全心全意完成一份实验。假如,假如这一学期只有这一门课,或者课少一些,那我觉得在这软构一方面的提升会有奇效(哈哈,瞎说的)。

以下就是正文了

二、实验内容

本次实验自由度非常的高,但也代表了工作量非常大,过程更加不易,也得到了手册中的方法启发,尝试了代码的可复用性,设计了ADT,甚至实现了客户端,收获良多。

本次需要开发三个应用:

1. 值班表管理(DutyRoster)

   在公司里,有 n 名员工。在指定的时间段内(例如,从1月10日到3月6日),每天只能安排一名员工值班,以确保没有漏掉任何时间段。如果一个员工被安排连续值班m 天(m>1),则必须在这连续的m天内安排。值班表中包含员工的姓名、职位和手机号码,以便外部联系值班员工。

2. 操作系统进程调度管理(ProcessSchedule)

假设计算机上有一个单核 CPU,操作系统创建并调度多个进程在 CPU 上运行。操作系统负责决定每个时间段内执行哪个进程,它可以挂起当前运行的进程,并在以后恢复其执行。在任何时刻,只能有一个进程在执行,其他进程处于休眠状态。进程的执行被分成多个时间片。在某些时候,CPU 可能处于“空闲”状态,即没有任何进程被调度执行。进程的调度由操作系统管理,可以被视为随机调度。

 3. 大学课表管理(CourseSchedule)

课程需要特定的教室和教师。在这个应用中,我们对课表进行了简化:假设某个班级的每周课表是固定的,每周重复相同的课程安排,直到学期结束。一门课程每周可以安排一次或多次(例如,“软件构造”可以安排在每周一和周三),并由同一位教师在同一间教室进行。课表中可以有空白时间段,即未安排任何课程。由于学生的选课不同,同一时间段内可以安排不同的课程(例如,周一上午第 3 到 4 节安排“计算方法”和“软件构造”)。一位教师可以承担课表中的多门课程。

1.面向可复用性和可维护性的设计:IntervalSet<L>

IntervalSet<L>描述了一组在时间轴上分布的“时间段”(interval),每个时间段附着一个特定的标签,且该标签不能够重复。将其共性的操作都放入IntervalSet<L>接口中封装起来。

其中,empty()方法设置为静态方法,其余方法设置为实例方法。

​​​​​​​局部共性特征的设计方案

为了提高代码的复用性,我们选择方案6来完成 IntervalSet 的局部共性特征的设计。方案6将 CommonIntervalSet 看作是原始的、未被装饰的对象,将“是否重叠”、“是否存在空闲”、“是否有周期性”这三个维度看作是三种“装饰”(每个维度的不同特征取值可以产生不同的“装饰”效果)。利用设计模式中的decorator方法,分别实现这些装饰,从而在具体应用中通过为一个 CommonIntervalSet 对象逐层装饰不同的特征,即可实现应用所需的组合特征。这种decorator设计模式的好处在于使得装饰类和被装饰类可以独立发展,彼此之间并没有太多的相互作用与影响。

​​​​​​​面向各应用的IntervalSet子类型设计(个性化特征的设计方案)

CommonIntervalSet<L>是IntervalSet<L>接口的具体实现类,implements了IntervalSet<L>中的方法,对其中的共性方法进行了实现。

CommonIntervalSet<L>,为其设置了两个成员变量:timeschedule与labelstimeschedule是一个HashMap,功能是以键值对的形式保存每个时间段。

对于timeschedule,键是泛型L,而值是长度为2的List<Long>,在List<Long>中,第一个位置保存时间段的起始值,第二个位置保持时间段的终点。由于IntervalSet具有每个时间段对应标签不可重复的特性,所以不用担心Map添加同样标签对应的键值对导致的覆盖问题。

对于labels,其为一个HashSet,保存着已经添加进IntervalSet的泛型L。

​​​​​​​2.面向可复用性和可维护性的设计:MultiIntervalSet<L>

与IntervalSet<L>不同的是,MultiIntervalSet<L>描述了一组在时间轴上分布的“时间段”(interval),且每个时间段对应的标签是可重复的,即:同一个标签对象 L 可被绑定到多个时间段上。在设计MultiIntervalSet时,还是构造一个接口,将MultiIntervalSet的共性的操作都放入MultiIntervalSet<L>接口中封装起来。

局部共性特征的设计方案

与IntervalSet类似,在针对MultiIntervalSet的局部共性特征进行设计时,同样采用了Decorator设计模式,实现了MultiIntervalSet<L>接口的抽象装饰类MultiIntervalSetDecorator,其中以MultiIntervalSet对象作为它的实例变量。在这之后,创建扩展了 MultiIntervalSetDecorator类的实体装饰类。对于MultiIntervalSet及其可能的应用场景(进程调度,课表安排),为其三个特征都实体装饰类:NoBlankMultiIntervalSet、NonOverlapMultiIntervalSet和NonPeriodicMultiIntervalSet,分别用于判断MultiIntervalSet中是否存在空闲,是否存在重叠,是否具有周期性。

​​​​​​​面向各应用的MultiIntervalSet子类型设计(个性化特征的设计方案)

为MultiIntervalSet<L>设计其具体的实现类CommonMultiIntervalSet<L>。在CommonMultiIntervalSet中,主要利用了委派的方法,基于IntervalSet实现其相关功能。

CommonMultiIntervalSet<L>中,设置了如下成员变量:

multi:multi是一个List,保存着不同的IntervalSet。IntervalSet中储存着标签与对应的时间段。

labels:保存标签,即已经添加进MultiIntervalSet的泛型L。

3.​​​​​​​面向复用的设计:L

IntervalSet<L>和 MultiIntervalSet<L>中的泛型参数 L,可以是任何 immutable的类。对于要开发的三个具体应用来说,L 分别应为“员工”(Employee)、“进程”(Process)、“课程”(Course)。于是分别实现这三个ADT。

由于这三个ADT均为immutable的,所以对于他们,均只设置Getter方法,不设置Setter方法。

由于同类ADT之间可能出现相互比较的情况,故对于每个ADT,均需要重写equals()与hashCode()方法。另外,为了表示统一,三个ADT一律只设计带参构造方法,不设置无参构造。

4.​​​​​​​可复用API设计

在本实验中,设置单独的APIs.java文件,用来保存以下可复用的方法:计算相似度、计算时间冲突比例、计算空间冲突比例。

5.​​​​​​​应用设计与开发

​​​​​​​排班管理系统

针对排班管理系统的功能要求,设计了具体的ADT子类型DutyIntervalSet与客户端DutyRosterApp

DutyIntervalSet中设计了如下方法:

DutyRosterApp应用了DutyIntervalSet类,为其构造了命令行前端页面。

​​​​​​​课表管理系统

针对排班管理系统的功能要求,设计了具体的ADT子类型CourseIntervalSet与客户端CourseScheduleApp。

CourseIntervalSet中设计了如下方法

CourseScheduleApp应用了CourseIntervalSet类,为其构造了命令行前端页面。

 

三、最后说一句感受

学习分先后顺序,有些人会先学会,有些人晚一些,所以在遇到问题时交流十分重要,自己闭塞的话只会让自己痛苦地原地抓狂,非常无助。

 

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值