2

我有一个具有生命周期的类,也就是说,随着时间的推移,它的一些属性会发生变化(即:如果你有一段时间不喝水,那么你会感到口渴)。现在我正在做的是有另一个类不断调用(而循环调用每分钟 x 时间量)第一个方法的一些方法,在那里我检查完成检查并执行适当的上一次行动。但是,我想要一些更干净的东西,也许可以使用一些模式来以更优雅的方式分离“观察”对象的责任。我希望它很清楚,否则我可以提供一些代码

4

5 回答 5

1

您可以使用“刻度”。使用刻度变量(整数)。每次调用方法时,将 tick 变量加一。

例如,如果您希望角色(或其他)在 250 个滴答声后感到口渴,只需将滴答声除以 250 并检查结果是否为 0。

于 2013-07-18T12:42:18.217 回答
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;
}
于 2013-07-18T12:36:57.633 回答
0

首先,我同意@Justin Amberson 所说的概念,这个概念是:

当状态被“请求”时,对象的状态将“改变”

这将是一种方式,但这可能取决于。

仅基于您的问题标题,上面的概念可能就足够了,但是(这与执行上下文的行为有关)如果这应该是“自动”行为,则可以在内部使用简单的类型来实现“调度程序”或“计时器”,根据对象状态,它们将等待下一个状态发生的时间量;在“计时器”等待时,如果操作(阻止状态更改)被“请求”,例如。“从现在起5分钟之前喝水”“计时器”将重新安排到下一次发生,以进行下一次状态变化。

正如我之前所说,这只是“想象”,因为仅基于您的问题标题和文本,第一个概念应该足够了,其余的超出了您的问题范围。

于 2013-07-18T13:03:40.473 回答
0

恕我直言,拥有一个自动更改其状态的对象不是一件好事,所以我认为不存在为此的设计模式。

正如有人向您建议的那样,我认为在您的对象中包含一个creationDate变量(或类似的东西)和几种方法来检查您的对象的“需求”可能是一个好主意。例如:

boolean isThirsty(){
    return (now - lastDrinkDate > MAX_INTERVAL);
}
于 2013-07-18T16:06:23.270 回答
0

首先,更改肯定需要在类内部处理;这就是正确的面向对象。如其他地方所述,最好的方法是在请求时计算每个值。

如果做不到这一点,你想运行一个计时器。理想情况下,您可以获得一个可以在某种队列(如 Java EventQueue)中运行的东西。这使所有内容都集中在一个线程中。否则,您将运行多线程,这可能会有些有趣。

最有可能的是,您可以从另一个类中获取代码并将其放入这个类中。无论如何,该代码已经不得不解决这些问题。

从哪里开始计时器可能是一个技巧。如果您已经有了某种激活方法,那么您就一切就绪。否则,如果您不是多线程的,只需在构造函数中启动它,这样类就可以从一开始就准备好。(除非您想在会话中多次启动和停止它。)您甚至可以在运行多线程时执行此操作,但如果您(或其他任何人)粗心或健忘,其他代码可以在完全初始化之前访问该类. 或者当然,如果没有运行计时器,一个新构造的实例还没有完全初始化,所以即使你使用激活方法也会遇到同样的问题。(我倾向于在两者之间摇摆不定,为每种情况选择最不坏的解决方案。希望你不是多线程的。)

如果您的整个会话可能不需要一个类实例,您将需要一个“dispose”方法,以及一个调用它的地方。(如果您有“激活”方法,请将其改为“停用”方法。在一个会话中多次激活和停用对象可能是有意义的。)

于 2013-07-18T19:19:46.363 回答