我有一个具有生命周期的类,也就是说,随着时间的推移,它的一些属性会发生变化(即:如果你有一段时间不喝水,那么你会感到口渴)。现在我正在做的是有另一个类不断调用(而循环调用每分钟 x 时间量)第一个方法的一些方法,在那里我检查完成检查并执行适当的上一次行动。但是,我想要一些更干净的东西,也许可以使用一些模式来以更优雅的方式分离“观察”对象的责任。我希望它很清楚,否则我可以提供一些代码
5 回答
您可以使用“刻度”。使用刻度变量(整数)。每次调用方法时,将 tick 变量加一。
例如,如果您希望角色(或其他)在 250 个滴答声后感到口渴,只需将滴答声除以 250 并检查结果是否为 0。
我要做的是将对象初始化时的系统日期记录为对象的属性。然后,不是“观察”对象,而是在对象内部有一个方法,通过将初始时间与当前时间进行比较来返回状态。
不一定会解决您的 while 循环问题...但根据您的实现,您可能不需要 while 循环(您可以在适合您时调用此对象方法)
编辑:
例如(抽象,这不是一种语言。从您的平台替换方法)
//MyObject.h
enum {
NormalObjectState = 0,
ThirstyObjectState = 1
} ObjectState;
SystemDate _initSystemDate;
-(ObjectState) returnObjectState;
//MyObject.m
- (MyObject) init {
SystemDate currentTime = GetSystemTime();
_initSystemTime = currentTime;
return self;
}
-(ObjectState) returnObjectState {
SystemDate currentTime = GetSystemTime();
SystemDateInterval timeInterval = GetTimePassed(_initSystemTime, CurrentTime);
ObjectState currentState = NormalObjectState;
if (timeInterval > 60) { //minute passed
currentState = ThirstyObjectState;
}
return currentState;
}
//in your program code
#import MyObject.h
//...
while (x) {
ObjectState currentObjectState = [object returnObjectState];
if (currentObjectState == NormalObjectState) {
print ("I'm normal");
} else {
print ("I'm thirsty");
[thisClass drinkWater];
}
}
- (void) drinkWater {
SystemDate currentTime = GetSystemTime();
_initSystemTime = currentTime;
}
首先,我同意@Justin Amberson 所说的概念,这个概念是:
当状态被“请求”时,对象的状态将“改变”
这将是一种方式,但这可能取决于。
仅基于您的问题标题,上面的概念可能就足够了,但是(这与执行上下文的行为有关)如果这应该是“自动”行为,则可以在内部使用简单的类型来实现“调度程序”或“计时器”,根据对象状态,它们将等待下一个状态发生的时间量;在“计时器”等待时,如果操作(阻止状态更改)被“请求”,例如。“从现在起5分钟之前喝水”“计时器”将重新安排到下一次发生,以进行下一次状态变化。
正如我之前所说,这只是“想象”,因为仅基于您的问题标题和文本,第一个概念应该足够了,其余的超出了您的问题范围。
恕我直言,拥有一个自动更改其状态的对象不是一件好事,所以我认为不存在为此的设计模式。
正如有人向您建议的那样,我认为在您的对象中包含一个creationDate
变量(或类似的东西)和几种方法来检查您的对象的“需求”可能是一个好主意。例如:
boolean isThirsty(){
return (now - lastDrinkDate > MAX_INTERVAL);
}
首先,更改肯定需要在类内部处理;这就是正确的面向对象。如其他地方所述,最好的方法是在请求时计算每个值。
如果做不到这一点,你想运行一个计时器。理想情况下,您可以获得一个可以在某种队列(如 Java EventQueue)中运行的东西。这使所有内容都集中在一个线程中。否则,您将运行多线程,这可能会有些有趣。
最有可能的是,您可以从另一个类中获取代码并将其放入这个类中。无论如何,该代码已经不得不解决这些问题。
从哪里开始计时器可能是一个技巧。如果您已经有了某种激活方法,那么您就一切就绪。否则,如果您不是多线程的,只需在构造函数中启动它,这样类就可以从一开始就准备好。(除非您想在会话中多次启动和停止它。)您甚至可以在运行多线程时执行此操作,但如果您(或其他任何人)粗心或健忘,其他代码可以在完全初始化之前访问该类. 或者当然,如果没有运行计时器,一个新构造的实例还没有完全初始化,所以即使你使用激活方法也会遇到同样的问题。(我倾向于在两者之间摇摆不定,为每种情况选择最不坏的解决方案。希望你不是多线程的。)
如果您的整个会话可能不需要一个类实例,您将需要一个“dispose”方法,以及一个调用它的地方。(如果您有“激活”方法,请将其改为“停用”方法。在一个会话中多次激活和停用对象可能是有意义的。)