1.实验概述
本次实验要求编写可复用性和可维护性的软件。涉及到子类型、泛型、多态、重写、重载、继承、代理、组合语法驱动的编程 、 正则表达式API设计 、 API复用等基本内容。通过 ADT和 泛型等抽象技术,开发一套可复用的 ADT及其实现,完成三个具体应用(值班表管理、 操作系统进程 调度管理 、大学课表管理)。
2.设计模式
在这个实验中,选择了委托的设计模式。通过接口组合实现局部共性特征的复用。每个维度分别定义自己的接口,针对每个维度不同特征取值,分别实现针对该维度接口的不同实现类,实现特殊逻辑操作。
通过接口组合,将局部共性行为组合在一起,形成满足每个应用要求的特殊接口。
对于应用2,使用MultiIntervalSet作为父类建立ProcessIntervalSet子类。
首先建立IProcessIntervalSet接口,这个接口继承NonOverlapIntervalSet<L>,BlankIntervalSet<L>, NonPeriodicIntervalSet<L>三个接口,即实现时间段无重叠,允许空闲时间以及没有周期性时间段三个特殊的要求。然后建立ProcessIntervalSet类继承MultiIntervalSet,并实现IProcessIntervalSet接口。接下来建立委托关系:
private NonOverlapIntervalSet<L> nois;
private BlankIntervalSet<L> bis;
private NonPeriodicIntervalSet<L> npis;
public ProcessIntervalSet(NonOverlapIntervalSet<L> nois,BlankIntervalSet<L> bis,NonPeriodicIntervalSet<L> npis)
{
this.bis = bis;
this.nois = nois;
this.npis = npis;
}
然后委托调用,完成特殊功能的实现:
public boolean insert(MultiIntervalSet<L> multiintervalset, long start, long end, L label) {
try{
return nois.insert(multiintervalset, start, end, label);
}catch(OverlapException e){
System.out.println("同一时间不允许允许多个进程!");
return false;}
对于应用3,使用MultiIntervalSet作为父类建立CourseIntervalSet<L>子类。
首先建立ICourseIntervalSet接口,这个接口继承OverlapIntervalSet<L>, BlankIntervalSet<L>, PeriodicIntervalSet<L>三个接口,即实现时间允许重叠,允许空闲时间以及有周期性时间段三个特殊的要求。建立如下的委托关系:
public CourseIntervalSet(OverlapIntervalSet<L> ois,BlankIntervalSet<L> bis,PeriodicIntervalSet<L>pis){
this.ois = ois;
this.bis = bis;
this.pis = pis;
}
3.局部共性实现
对于三个层次的不同,主要主要包含六个方面。这里采用的是方案5,所以设计了6个接口分别对应三个层次6中情况。
1.无空闲时间
为此定义接口NoBlankIntervalSet,接口中定义了方法
public List<interval> checkNoBlanck(IntervalSet<L> intervalset,long allstart,long allend);
这个方法检查intervalset中是否有空白,然后返回空白段。若时间轴设置了开始和技术时间,空白段的计算将会考虑这两个参数。若时间轴没有设置开始和结束时间,将这两个参数设置为-1可以忽略。
检查空白段的方法为,使用getintervalset得到所有时间段的集合。将所有开始时间(start)从小到大放入一个List,将所有结束时间(end)从小到大放入一个List。根据这两个集合,计算空白块。判断的方法为,若第i+1个start大于第i个end则存在空白快,将这个空白块加入要返回的空白块集合。此外,考虑是否给定了时间轴的开始时间和结束时间,否则以第一个开始时间作为时间轴的起始。
Collections.sort(starts);
Collections.sort(ends);//排序时间
for(int i =0;i<ends.size()-1;i++){//遍历
if(starts.get(i+1).longValue()>ends.get(i).longValue())
blank.add(new interval(ends.get(i).longValue(),starts.get(i+1).longValue());}
原理:若有空白块存在,则必然是前一个时间段的end与后一个时间段的start之间存在距离,且这一段时间轴上没有其他的时间段。当第i个end出现的时候,前面必然有i个start已经出现,也就是从end(i)往前有i个时间段。start(i+1)比end(i)大,说明start(i+1)也就是第i+1个时间段出现在前i个时间段之后,且与前i个时间段没有交集。
此外,NoBlankIntervalSetImpl中还提供了获得时间轴的总开始时间和结束时间的方法。
wqdqdsa dsaxzcxczxvdewgew