Swimmer类
除了说过Swimmer类含有名字、俱乐部、年龄、排位、时间以及在选拔赛后的分组和泳道外,
对Swimmer类我们并没有介绍太多。Event类从某个数据库(在例子中用的是一个文件)读入
Swimmer数据,然后在为某项赛事调用getSeeding方法时,将数据传给Seeding类。
Event类
我们在前面已经看到了抽象基类Event在实际应用中,用它读入选手数据,并将其传给Swim-
mer类的一个实例去进行分析。在抽象基类Event里,判断赛事是预赛、决赛还是计时决赛的方法
都是空的,在派生类中会实现这些方法。
PrelimEvent类返回CircleSeeding的一个实例。
csharp
public class PrelimEvent:PrelimEvent
{
public PrelimEvent(string filename,int lanes);
base(filename,lanes)
{
}
public override Seeding getSeeding()
{
return new CircelSeeding(swimmers,numLanes);
}
public override bool isPrelim()
{
return true;
}
public override bool isFinal()
{
return false;
}
public override bool isTimedFinal()
{
return false;
}
}
TimedFinalEvent类返回StraightSeeding的一个实例。
csharp
public class TimedFinalEvent:Event
{
public TimedFinalEvent(string filename,int lanes):base(filename,lanes)
{
}
public override Seeding getSeeding()
{
return new StraightSeeding(swimmers,numLanes);
}
public override bool isPrelim()
{
return false;
}
public override bool isFinal()
{
return false;
}
public override bool isTimedFinal()
{
return true;
}
}
在这两段代码中,两种赛事类都包含基类Event的一个实例,用它读取数据文件。
直接排位
实际编写这个程序时,我们发现大多数工作都是在直接排位(StraightSeeding)中完成的,为
循环排位(CircleSeeding)而进行的改动相当少。实例化StraightSeeding类,并拷人选手数据和泳
道号。
csharp
protected override void seed()
{
sortUpwards();
int lastHeat=count%numLanes;
if(lastHeat<3)
lastHeat=3;
int lastLanes=count-lastHeat;
numHeats=count/numLanes;
if(lastLanes>0)
numHeats++;
int heats=numHeats;
}
这段程序的目的是,在调用getSwimmer方法时,使选手排位的整个数组都是可用的。
循环排位
CircleSeeding类从StraightSeeding类派生,因此一开始先调用父类的seed方法,然后重新安排
比赛。
csharp
protected override void seed()
{
int circle;
base.seed();
if(numHeats>=2)
if(numHeats>=3)
circle=3;
else
circle=2;
int i=0;
for(int j=0;j<numLanes;j++)
{
for(int k=0;k<circle;k++)
{
swmrs[i].setLane(lanes[j]);
swmrs[i++].seatHeat(numHeats-k);
}
}
}
排位程序
在这个例子中,我们从网上拿到了参加500yd(码,1yd=0.914(m)和100yd自由泳比赛
的选手数据,井使用这些数据构建类TimedFinalEvent和PrelimEvent类。在图9.2里,会看到这
种排位方式的结果。在上面的图中,选择的是500Event事件,可以看到选手按照由快到慢的顺序直
接安排泳道。在下面的图中,选择的是事件,进行的是循环排位。
其他工厂
我们在前面略过了一个问题:读入运动员数据的程序如何决定生成哪一项赛事。在我们读入
数据时,通过创建正确类型的事件来巧妙地实现这一点。这部分代码在窗体的init方法中。
csharp
private void init()
{
private void init()
{
events=new ArrayList();
lsEvents.Items.Add("500 Free");
lsEvents.Items.Add("100 Free");
events.Add(new TimedFinalEvent("500free.txt",6));
events.Add(new PrelimEvent("100free.txt",6));
}
}
很明显,这是一个需要EventFactory来决定生成哪一项赛事的例于,这又涉及到了我们开始时
而讨论的简单厂。
何时使用工厂方法
在下列情况下,应该考虑使用工厂方法:
- 一个类无法预测它要创建的对象属于哪一个类。
- 一个类用它的子类来指定所创建的对象。
- 把要创建哪一个类的信息局部化的时候。