OOP 观察者模式:从主题外部调用 notifyListener

OOP Observer Pattern: call notifyListener from outside of the subject

Observer 对象在更改其某些字段后调用 notifyListeners() 是否可以?会出现什么缺点?通常,通知听众更改是主题的责任。

在将模型 classes 包装在可观察对象/主题中时,我经常遇到以下问题,例如使它们可以在 UI 中访问。

我的主题是否应该在模型对象的任何字段发生更改时通知其听众,或者我是否应该提供某种方法 setModel() 将新模型对象作为参数,然后才通知所有听众?

例如:

class MyData {
  String myString;
  int myInt;
}

class MyDataObservable {
  private MyData data;

  // constructor

  void setString(String string) {
    data.myString = string;
    notifyListeners();
  }

  void setInt(int num) {
    data.myInt = num; 
    notifyListeners();
  }

  void notifyListeners() {...}

  void addListener(Observer o) {...}
}

我不喜欢我的主题基本上反映了我模型的所有属性.. 这非常丑陋。

class MyDataObservable {
  private MyData data;

  // constructor

  void setData(MyData data) {
    this.data = data; 
    notifyListeners();
  }

  void notifyListeners() {...}

  void addListener(Observer o) {...}
}

这种方法的缺点是每次发生任何变化时,我都必须构建一个新的数据副本 class,即使它只是我模型上的一个 bool 标志 class。

所以我的想法是允许观察者在他们改变某些东西时通知其他听众,例如update 函数。

还有其他更优雅的选择吗?

编辑

目前,使我的数据 class 成为可观察的不是一种选择,因为我使用的框架提供了可观察的机制,该机制也可以保存业务逻辑。出于这个原因,我想分离我的数据 class 和逻辑/可观察的。

在这种情况下,我会使用继承而不是组合:MyData is-a Observable 而不是 Observable 有一个 MyData.

class Observable {
    Collection<Listener> listeners

    void addListener(Listener l) {...}
    void notifyListeners() {...}
}

class MyData extends Observable {
    String myString;
    int myInt;

    void setString(String string) {
        this.myString = string;
        notifyListeners();
    }

    void setInt(int num) {
        this.myInt = num; 
        notifyListeners();
    }
}