РЕДАКТИРОВАТЬ: я написал свой ответ несколько лет назад. Прочитав это только сейчас, я почувствовал, что мне нужно обновить его.
Я полагаю, что лучший подход - это уведомить всех наблюдателей и позволить взглядам решить, нужно ли им обновляться.
Каждое представление сможет проверить состояние модели и действовать соответственно.
Кроме того, «args» можно использовать в качестве флага, чтобы указать, что изменилось (представление может не захотеть обновляться при каждом небольшом изменении).
Таким образом, модель ДЕЙСТВИТЕЛЬНО не знает, как и что отображает вид, они разъединены.
Первая реализация будет выглядеть так:
public class MyModelV1 extends Observable {
private int value;
public void setValue(int value) {
this.value = value;
setChanged();
notifyObservers();
}
public int getValue() {
return value;
}
}
public class MyViewV1 implements Observer {
public void update(Observable o, Object arg) {
if (o instanceof MyModelV1) {
System.out.println(((MyModelV1) o).getValue());
}
}
}
Представление просто проверяет тип получаемой наблюдаемой.
Однако, если модель имеет много атрибутов и запускает представление для множества различных сценариев, эта простая проверка может обновлять представление слишком часто.
Другой подход будет следующим:
public class MyModelV2 extends Observable {
private int value;
public void setValue(int value) {
this.value = value;
setChanged();
notifyObservers("value");
}
public int getValue() {
return value;
}
}
public class MyViewV2 implements Observer {
public void update(Observable o, Object arg) {
if (o instanceof MyModelV2 && "value".equals(arg)) {
System.out.println(((MyModelV2) o).getValue());
}
}
}
Здесь уведомление проходит квалификатор, который позволяет представлению более точно определить, когда обновлять себя.
Представлению по-прежнему необходимо проверять и приводить модель, поскольку нет гарантии, что arg "value" не будет уведомлено другой моделью (и приведение не будет выполнено во время выполнения).
Мой личный фаворит - что-то вроде этого:
public class MyModelV3 extends Observable {
private int value;
public void setValue(int value) {
this.value = value;
setChanged();
Notification.MY_MODEL_VALUE_UPDATED.notifyObserver(this);
}
public int getValue() {
return value;
}
}
public class MyViewV3 implements Observer {
public void update(Observable o, Object arg) {
if (Notification.MY_MODEL_VALUE_UPDATED.equals(arg)) {
MyModelV3 model = Notification.MY_MODEL_VALUE_UPDATED.getModel(o);
System.out.println(model.getValue());
}
}
}
public class Notification<T extends Observable> {
public static final Notification<MyModelV3> MY_MODEL_VALUE_UPDATED = new Notification<MyModelV3>();
private Notification() {
}
public T getModel(Observable o) {
return (T) o;
}
public void notifyObserver(T observable){
observable.notifyObservers(this);
}
}
Здесь уведомление отправляет строго типизированный квалификатор, который привязан к модели.
Представление может использовать уведомление для извлечения строго типизированной модели (вместо приведения).
Это где-то между наблюдателем и шиной событий.