samedi 15 février 2020

OOP Observer Pattern: call notifyListener from outside of the subject

Is it ok for an Observer object to call notifyListeners() on an observable after changing some of its fields? What disadvantages could arise? Usually it's the subjects' responsibility to notify listeners of changes.

I frequently come across the following problem when wrapping model classes in an observable / subject e.g. to make them accessible in UI.

Should my subject notify its listeners whenever any field of the model object is changed or should I provide some kind of method setModel() that takes a new model object as an argument and only then notifies all listeners?

For example:

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) {...}
}

I don't like that my subject basically mirrors all the properties of my model .. which is pretty ugly.

class MyDataObservable {
  private MyData data;

  // constructor

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

  void notifyListeners() {...}

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

The downside of this approach is that I have to build a new copy of my data class everytime anything changes, even if it's just a bool flag on my model class.

So my idea was to allow for observers to notify other listeners when they changed something with e.g. an update function.

Are there other, more elegant alternatives?

Aucun commentaire:

Enregistrer un commentaire