【问题标题】:how to design a class where the object state will vary depending on time?如何设计一个对象状态会随时间变化的类?
【发布时间】:2013-07-17 09:48:02
【问题描述】:

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

【问题讨论】:

  • 既然你暗示了一个游戏机制,如果你想让我把这个问题迁移到gamedev.stackexchange.com,请回复这个评论

标签: class oop design-patterns object


【解决方案1】:

我要做的是将对象初始化时的系统日期记录为对象的属性。然后,不是“观察”对象,而是在对象内部有一个方法,通过将初始时间与当前时间进行比较来返回状态。

不一定能解决您的 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;
}

【讨论】:

  • 这基本上就是我正在做的,所以我认为这是我们能做的最好的事情
  • @davioooh 下面的另一个答案引用了“lastDrinkDate”来强制状态恢复正常。我提供的大纲没有说明这一点。在代码中添加了一个喝水方法来解决口渴的对象状态
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      boolean isThirsty(){
          return (now - lastDrinkDate > MAX_INTERVAL);
      }
      

      【讨论】:

        【解决方案5】:

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

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

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

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

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

        【讨论】:

          猜你喜欢
          • 2016-08-13
          • 1970-01-01
          • 1970-01-01
          • 2011-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-19
          • 1970-01-01
          相关资源
          最近更新 更多