从嵌套结构中通知观察者

时间:2011-07-11 09:52:49

标签: oop design-patterns observer-pattern

目前,我试图通过引入MVC模式来剖析应用程序中数据模型和UI之间的一些紧密耦合。基本上,这意味着让模型知道相关的视图,以便在模型内的属性发生变化时通知它们。

数据模型由嵌套结构表示:

Model
- Node
  - Leaf
  - Leaf
- Node
  - Leaf

每个元素都继承自一个公共抽象基类(StructuredNode)。

我一直在考虑的问题是:观察者应该能够订阅模型(并且只能模型化),但每个元素都应该能够发出更改通知。这可以通过两种方式实现 - 通知在层次结构中路由,直到它们到达模型,在那里它们被推送到观察者,或者通过在基类中实现通知,使用静态观察者列表,如下例所示: / p>

public abstract class Base {

  private static Map<IObserver> observers;


  protected synchronized void internalSubscribe(final IObserver observer) {
    observers.add(observer);
  }

  protected synchronized void notifyObservers(final Base obj) {
    for (IObserver observer : observers)
      observer.changed(obj);
  }

  // .. other base class operations
}

在此实现中,只有Model会提供一个公共订阅方法,该方法在内部委托给基类的受保护的internalSubscribe方法。同时,基类的每个派生都可以发送更改通知,如下所示:

// Perform some operations that change the object's internal state
// ...
// Then notify all observers
notifyObservers(this);

这是相当好的还是相当糟糕的做法(使用静态观察者列表)?有什么意见吗?有替代解决方案吗?

1 个答案:

答案 0 :(得分:1)

静态观察者列表不是一种常见的解决方案,我不认为它是通用使用模型的好习惯。

观察员将被告知他们不感兴趣的模型的变化。这意味着识别触发通知的模型的所有负担都落在观察者身上,除了上升之外,这可能没有好的和有效的方法。层次结构和查找根节点...很多代码,必须在几个观察者中多次实现。最后,观察者更容易忽略注意事项,只更新或重新计算,即使更新的模型不是它感兴趣的模型。

当然,所有这些可能不适用于您的情况。如果您知道在您的应用程序中不会有多个此类的模型,那么您可以很好地使用此解决方案。

无论如何,只有具有公共订阅方法的Model的要求不应该限制您使用静态观察器容器在所有Model实例之间共享。正如你所说,还有另一种方式。将通知路由到层次结构是恕我直言,这是正确的方法。

如果您想避免路由,那么您可以选择让节点保持对其模型的引用。如果您知道树结构将是非常动态的,那么这可能会更有效。如果节点可以从一个模型移动到另一个模型,那么这有点风险,需要一些进一步的代码来保持参考更新。