此次实验难度很高,任务量尤其重,因此特别写一些感想在这里吧。 建议以后的学弟学妹一定要早些早完事。留下一些自己的想法在这里。
面向ADT的编程,是单纯的目的驱动性。但是面对应用场景,需要考虑编程上的技巧和效率。提高ADT的抽象程度,提高复用性,多考虑实际应用场景的问题,才能成为更好的程序员。
接口,给予我们一个复用性的基础,以及泛型的使用方法。尤其在大工程的开发中,首先设计好接口很重要。类的继承在特定场景很有用,但是由于存在组合爆炸问题,在此次实验中,我还是更倾向于委托。抽象类的功能非常强大,放开了很多限制。
在实现任务具体功能之前,务必好好想一想自己的具体实现策略和模式。一个好的抽象和复用性会给你的实验带来事半功倍的效果。不同于面向过程的C语言编程,这里的更加强调面向对象的编程技巧。我们不能单纯依靠着,走一步看一步的想法,提前写好策略,优化底层,会给自己带来想不到的收获和财富。
- 实验目标概述
本次实验覆盖课程第 2、3 章的内容,目标是编写具有可复用性和可维护性
的软件,主要使用以下软件构造技术:
l 子类型、泛型、多态、重写、重载
l 继承、代理、组合
l 语法驱动的编程、正则表达式
l API 设计、API 复用
本次实验给定了三个具体应用(值班表管理、操作系统进程调度管理、大学
课表管理),学生不是直接针对每个应用分别编程实现,而是通过 ADT 和泛型等
抽象技术,开发一套可复用的 ADT 及其实现,充分考虑这些应用之间的相似性
和差异性,使 ADT 有更大程度的复用(可复用性)和更容易面向各种变化(可
维护性)。
- 实验环境配置
同往常实验一样
在这里给出你的GitHub Lab3仓库的URL地址(Lab3-学号)。
- 实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
-
- 待开发的三个应用场景
三个应用场景:
排班管理系统
操作系统的进程调度管理系统
课表管理系统
共性:
1.他们最大的共同点就是,都是以时间段为安排,也就是都是按照时间集合进行安排和划分的。
2.首先需要输入一组包含名称,起始末尾的集合信息
3.每个对象可以有不同的时间集合,可以对应一整个时间集合。
4.都需要设定明确的起始点和结束点,
5.对于各个时间段能否冲突都需要要明确的讨论。
6.每一个时间段都会唯一匹配一个对象
差异:
1.排班表中如果某个员工已经被编排进排班表,那么他不能被删除,必须将其排班信息删掉之后才能删除该员工。员工信息一旦设定则无法修改。
2.排班表时间是必须排满的,排课的时候是可以存在空闲的。
3.进度安排中还需要特别考虑有最小最优的时间安排。
4.课表排课允许有空闲时间,并且需要加入周期的概念。
-
- 面向可复用性和可维护性的设计:IntervalSet<L>
该节是本实验的核心部分。
-
-
- IntervalSet<L>的共性操作
-
1.插入一个新的时间段
2.返回所有的对应标签
3.移除一个标签对应的所有时间段
4.分别返回起始时间和结束时间
5.返回一个空的对象
-
-
- 局部共性特征的设计方案
-
1.解决时间段重叠问题
2.解决空闲时间段问题
3.解决周期性问题
-
-
- 面向各应用的IntervalSet子类型设计(个性化特征的设计方案)
-
- CourseIntervalSet
2.ProcessScheduleApp
3.DutyRosterApp
-
- 面向可复用性和可维护性的设计:MultiIntervalSet<L>
- MultiIntervalSet<L>的共性操作
- 面向可复用性和可维护性的设计:MultiIntervalSet<L>
- 插入操作,允许多个标签的插入
- 移除标签
- 返回标签集合
- 按顺序返回intervals集合
-
-
- 局部共性特征的设计方案
-
- 周期性补充
- 装饰器添加
-
-
- 面向各应用的MultiIntervalSet子类型设计(个性化特征的设计方案)
-
1.CourseIntervalSet
2.ProcessScheduleApp
3.DutyRosterApp
-
- 面向复用的设计:L
IntervalSet<L> 标签不重复的ADT
MultiIntervalSet<L> 标签重复的ADT
multi_decorator<L> 构造multinterval的装饰器
Set<L> 泛型集合
dutyintervalset<L> 值班表
act_interval_noblank<L> 非空时间段的实现
multi_period<L> 增加周期性
interval_cope_overlap<L> 解决重叠问题
interval_decorator<L> 构造interval的装饰器
courseintervalset<L> 排课表
processintervalset<L> 值班表
-
- 可复用API设计
- 计算相似度
- 可复用API设计
首先找到,最大和最小的时间点,计算出差得到整个时间长度。遍历集合,找到标签相同的一个,然后把相同的时间段累加,除以整个时间段。
-
-
- 计算时间冲突比例
-
两两枚举集合中的两个元素,找到他们重合的部分,然后加入到一个新的集合。加入到集合的过程中,再次进行新的集合遍历,保证不会和集合中其他的元素重合。如果有重合,那么就拆分成新的不重合部分,然后加入。
-
-
- 计算空闲时间比例
-
两两枚举时间段,把没有重合的,即断开的那些空闲时间段加入到新的集合中。同上一个问题的操作一样。如果新加的空闲时间段和集合中的时间段有重合,那么就进行拆分。
-
- 应用设计与开发
利用上述设计和实现的ADT,实现手册里要求的各项功能。
-
-
- 排班管理系统
-
- 初始时,设置值班表的开始和结束时间。
新建dutyintervalset对象插入时间就可以了。
- 输入指令2,添加员工信息,按照逗号分开,然后分别读入数据再insert
- 删除员工信息,将对应对象remove即可
- 自动设置排班信息,能者多劳,若一人一天能分完就正好结束,如果分不完,就让最后的几个人承担剩下的劳动。
- 查看排课表情况,查看空闲时间段集合是否为空即可。
- 从外部读入信息员工信息,设计良好的正则表达式!
-
-
- 操作系统的进程调度管理系统
-
- 初始时,添加一系列的进程信息
新建processintervalset对象插入时间然后,按照逗号分开,然后分别读入数据再insert
2.随机模拟进程,利用random库生成的随机数决定当前进程。
3.可以输入挂起指令将进程挂起,输入恢复指令,进程会继续进行判断状态是否为挂起,如果挂起就停止。
4.按照最短时间安排进度,排序计算,重写compare优先时间最短的进程先执行。
5.显示最终的结果以及进程的结束
-
-
- 课表管理系统
-
- 初始时,设置本学期的起末时间以及总周数。新建dutyintervalset对象插入时间就可以了。
- 输入指令2,添加相应的课程具体信息,包括ID,课程名,教师名称和教室
- 搜索相应的课程ID,并且把它删去。
分别insert相关信息进去,如果要删除的时候,就把找到的对应人remove
4.设置课程的具体上课时间
5.查看课程表中已经添加的课程信息
6.输入指令7,可以计算空闲时间的总占比
7.输入指令8,可以计算课程重复时间占比
8.输入指令9,然后可以查看指定日期的上课信息
9.重新输入信息后,可以查看未被添加进课程表的信息,输入10退出课程
-
- 基于语法的数据读入
设计一个正则表达式,然后和文件中的文本信息进行匹配读取,保证正确读入相应的员工信息。
设置文档读入,调整格式
-
- 应对面临的新变化
- 变化1
- 应对面临的新变化
也可以修改,之前采用的不可空白类中,继承的是intervalset。那么我们只需要将其修改成multintervarset,那么就可以完成目的要求的功能了。
-
-
- 变化2
-
之前的设计可以应对变化,代价只是在multintervarset的具体实现中如果遇到了时间冲突的插入那么就直接拒绝并且抛出异常即可。