Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Model view controller 在MVC中通知观察者的最佳方式?_Model View Controller_Design Patterns - Fatal编程技术网

Model view controller 在MVC中通知观察者的最佳方式?

Model view controller 在MVC中通知观察者的最佳方式?,model-view-controller,design-patterns,Model View Controller,Design Patterns,假设某个视图感兴趣的模型中有5或6个变量,您是否为每个变量编写了不同的函数,例如 int a; int b; int c; void setA( newA ) { a = newA; notifyAObservers(); } void setB( newB ) { b = newB; notifyBObservers(); } void setC( newC ) { b = newC; notifyCObservers(); } 还是只有一种通知方法

假设某个视图感兴趣的模型中有5或6个变量,您是否为每个变量编写了不同的函数,例如

int a;
int b;
int c;

void setA( newA ) {
   a = newA;
   notifyAObservers();
}

void setB( newB ) {
   b = newB;
   notifyBObservers();
}

void setC( newC ) {
   b = newC;
   notifyCObservers();
}
还是只有一种通知方法,浪费了一点CPU时间

i、 e.与NotifyAObserver和NotifyBobserver不同,您只需要notifyObservers,我认为最重要的是通知所有观察者,并让他们处理。这是因为你不知道哪些观察者正在观察哪些变量——你只知道他们希望在某些事情发生变化时得到通知。然而,如果您确实知道观察者在观察哪些变量,并且性能非常关键,那么您可能可以做一些类似于您所做的事情

在传统的观察者模式中,观察者实现一个update()方法,当发生更改时,控制器会调用该方法。观察对象(数据模型)将有一个notifyObservators()方法,该方法迭代观察对象并调用其update()方法。然后,观察者得到他们需要的任何东西,视图更新


然而,每当我实现了观察家模式时,我都会简单地保留一个观察家列表并通知他们所有人。这样,我只有一个观察者列表,而班上的其他人以及不同的观察者都可以更改,而无需我对可观察的类通知进行任何更改。

编辑:几年前我写了我的答案。刚刚读完之后,我觉得我需要更新一下

我认为最好的办法是通知所有观察者,让他们决定是否需要更新自己

每个视图将能够验证模型的状态并相应地采取行动。 此外,“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);
    }
}
公共类MyModelV3扩展了可观察{
私有int值;
公共无效设置值(int值){
这个值=值;
setChanged();
通知.MY_MODEL_VALUE_UPDATED.notifyObserver(此);
}
public int getValue(){
返回值;
}
}
公共类MyViewV3实现了Observer{
公共无效更新(可观察o,对象arg){
if(通知.MY_MODEL_VALUE_UPDATED.equals(arg)){
MyModelV3 model=Notification.MY\u model\u VALUE\u UPDATED.getModel(o);
System.out.println(model.getValue());
}
}
}
公开课通知{
公共静态最终通知MY_MODEL_VALUE_UPDATED=新通知();
私人通知(){
}
公共T模型(可观测o){
返回(T)o;
}
公共观察者(T可观察){
可观察。通知观察者(本);
}
}
这里,通知发送一个绑定到模型的强类型限定符。 视图能够使用通知检索强类型模型(而不是强制转换)


这是介于观察者和事件总线之间的某个位置。

它还使事情变得简单,因为有办法找出哪些观察者正在观察哪个变量。然而,这最终可能看起来很复杂。你能给我举个简单的例子吗,托马斯?我已经投票支持你,但是在视图中将实现哪些方法,如何通知他们,等等。谢谢!你的意思是说所有的观察者只需实现一个“notify()”方法,然后他们每次都会轮询模型中他们感兴趣的数据。例如,notifyObservators()直接遍历观察者列表并调用notify()。每个观察者从模型中提取所需的数据,并相应地更新其视图。就像变量A被更改一样,B-Observators仍然会得到一个notify()调用,并且会说类似于B=model.getB(),即使B没有更改?我不确定您在寻找什么-我文章中的链接有Java和Python中的Observator模式示例。你能详细说明你有什么具体问题吗?当我发表我的评论时,你发表了你的第二条评论。但是是的,你是对的。我也在我原来的帖子中添加了这个。