如何避免Observer模式中的无限循环?

jos*_*eph 4 java design-patterns

我只有一个有很多实例的类.每个实例都是其他几个实例的观察者.同样,每个实例都可以被另外几个实例观察到.

如何避免在观察者中调用update()的无限循环?

And*_*bel 6

您正在寻找一种可检测循环的图遍历算法。一种简单的方法(仅在单线程方案中有效)是保持全局/静态计数器,以使每个顶级update()调用都获得唯一的标识符。然后,每个观察者都跟踪是否已经使用给定的标识符(ID)处理了更新,并且在这种情况下将其忽略。这意味着您的update方法将必须使用带有特定更新ID号的参数进行扩展。


jam*_*mes 6

如果您的系统是单线程的,那么您只需要在notify方法中使用一个guard:

private boolean _notifying;

public void notify() {
  if(_notifying) {
    return;
  }
  _notifying = true;
  try {
    // ... do notifying here...
  } finally {
    _notifying = false;
  }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*gón 5

好吧,如果要定义“事件”对象,则可以向其中添加已经处理过事件的对象。在这种情况下,如果关闭循环,则可以退出。用伪代码

eventFired(Event e)
  if (e.hasBeenEvaluatedBy(this)){
    return;
  }
  e.addEvaluator(this);

  // Do magic

  refire(e);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们得到如下信息:*发射东西。* B处理它并将其自身添加到列表中* B重新激发* C处理事件并将其自身添加到列表中* C重新激发* A处理该事件并将其自身添加到列表中* A重新激发* B捕获了该事件,但是已经存在列表。没有重击,无限循环中断

可以使用ID代替指针来避免垃圾回收问题