2009年5月21日星期四

TimeMachine

手上在写的程序希望能够跑着就不要人管,但只在工作日的9:00到11:30,13:30到15:30做需要做的事,其他时间休息。

所以我设计了一个WorkTimeController,它有3个方法:
void waitTillStartTime();
void skipLunchTime();
boolean afterEndTime();

waitTillStartTime()负责跳过双休日、国定假日,直到工作日的9:00为止。它在8:00之前,会sleep(ONE_HOUR),再检查一下时间。在8:00之后,会sleep(ONE_MINUTE),再检查一下时间。

skipLunchTime()在工作时间会立即返回,在午休时间会sleep(ONE_MINUTE),再检查一下时间。

afterEndTime()判断是否在15:30以后了。

工作程序有一个doOneDayJob()方法:
void doOneDayJob() {
workTimeController.waitTillStartTime();
while (true) {
doSomeJob();
workTimeController.skipLunchTime();
if(workTimeController.afterEndTime()) {
break;
}
}
}
这样就完成了一天的工作。

现在的问题是,如何来验证这些时间控制动作都是正确的?难道只有让时间来证明?“Time, goes by, so slowly...”

于是我设计了一个TimeMachine接口,包含两个方法:
long currentTimeMillis();
void sleep(long time);
WorkTimeController使用TimeMachine来获取当前时间和休息。

TimeMachine的正常实现是很直接的,我设计它的目的在于,可以实现一个MockTimeMachine。这个MockTimeMachine的sleep方法什么也不做,立即返回。而它的currentTimeMillis方法则依次返回一组预先设定好的时间。这样,我们就得到了一个时光机,可以检测在一些关键的时间点程序行为是否正常。

时间是一个关注点,在这个例子里,我们实现了时间关注点的分离,改善了程序的可测试性。

没有评论: