OOP Шаблон наблюдателя: вызвать notifyListener извне субъекта - PullRequest
0 голосов
/ 15 февраля 2020

Можно ли объекту Observer вызывать notifyListeners() для наблюдаемой после изменения некоторых ее полей? Какие недостатки могут возникнуть? Обычно субъекты обязаны уведомлять слушателей об изменениях.

Я часто сталкиваюсь со следующей проблемой, когда оборачиваю классы модели в наблюдаемый / субъект, например, чтобы сделать их доступными в пользовательском интерфейсе.

Должен ли мой субъект уведомлять своих слушателей всякий раз, когда изменяется любое поле объекта модели, или я должен предоставить какой-то метод 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) {...}
}

Недостатком этого подхода является то, что мне приходится создавать новую копию моего класса данных каждый раз, когда что-то меняется, даже если это просто флаг bool в моем классе модели.

Таким образом, моя идея состояла в том, чтобы позволить наблюдателям уведомлять других слушателей, когда они что-то меняли, например, с помощью функции update.

Существуют ли другие, более элегантные альтернативы?

РЕДАКТИРОВАТЬ

В настоящее время сделать мой класс данных наблюдаемым не вариант, потому что я использую инфраструктуру, которая обеспечивает наблюдаемый механизм, который также может поддерживать бизнес логи c. По этой причине я хочу отделить мой класс данных и logi c / observable.

1 Ответ

0 голосов
/ 15 февраля 2020

В этом случае я бы использовал наследование, а не композицию: MyData is-a Observable, а не Observable has-a 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();
    }
}
...