编辑:几年前我写了我的答案。刚刚看完,觉得有必要更新一下。
我认为最好的方法是通知所有观察者,让意见决定他们是否需要更新自己..
每个视图都能够验证模型的状态并采取相应的行动。
此外,“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());
}
}
}
视图只是检查接收到的 observable 的类型。
但是,如果模型有很多属性并且会针对很多不同的场景触发视图,那么这种简单的检查可能会过于频繁地刷新视图。
另一种方法如下:
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“值”没有被另一个模型通知(并且转换会在运行时失败)。
我个人最喜欢的是这样的:
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);
}
}
这里,通知发送一个强类型限定符,它绑定到模型。
视图能够使用通知来检索强类型模型(而不是强制转换)。
这介于观察者和事件总线之间。