java - 观察者模式无限循环

标签 java design-patterns infinite-loop observer-pattern

我遇到一种情况,当我有一个观察者同时也是一个主题时。 让我们想象一下有两个实体 A 和 B。 当 A 的模型发生变化时,其他实体应该知道,包括 B(C、D...等)。

当 B 的模型发生变化时,其他实体应该知道,包括 A(C、D...等)。

通过以这种方式实现观察者模式,我在 A 和 B 之间得到了无限循环。

观察者模式是否没有正确实现,或者我是否需要另一个模式来处理这种设计?

无论如何,她是我的实现

public interface ISubject {
    public void registreObserver(IObserver obs);

    public void removeObserver(IObserver obs);

    public void notifyObservers();
}

和观察者界面

public interface IObserver {
    public void update(ISubject subject);
}

模型

import java.util.ArrayList;
import java.util.List;


public class AModel implements ISubject {

    private List<IObserver> listObservers = new ArrayList<>();
    @Override
    public void registreObserver(IObserver obs) {
        listObservers.add(obs);
    }

    @Override
    public void removeObserver(IObserver obs) {
        listObservers.remove(obs);
    }

    public void loadData(){
        notifyObservers();
    }

    @Override
    public void notifyObservers() {
        for (IObserver obv : listObservers) {
            obv.update(AModel.this);
        }
    }
}

B模型

导入java.util.ArrayList; 导入java.util.List;

public class BModel implements ISubject {

    private List<IObserver> listObservers = new ArrayList<>();
    @Override
    public void registreObserver(IObserver obs) {
        listObservers.add(obs);
    }

    @Override
    public void removeObserver(IObserver obs) {
        listObservers.remove(obs);
    }

     public void loadData(){
        notifyObservers();
    }


    @Override
    public void notifyObservers() {
        for (IObserver obv : listObservers) {
            obv.update(BModel.this);
        }
    }
}

A Controller

public class AController implements IObserver {

private AModel model;

public void setModel(AModel model) {
    this.model = model;
}

    @Override
    public void update(ISubject subject) {
        System.out.println(" A Changed");
       model.loadData();
    }
}

B Controller

public class BController implements IObserver {

private BModel model;

public void setModel(BModel model) {
    this.model = model;
}
    @Override
    public void update(ISubject subject) {
        System.out.println(" B Changed");
model.loadData();
    }
}

主程序

public class Main {

    public static void main(String[] args) {
        AModel aModel = new AModel();
        AModel bModel = new BModel();

        AController aController = new AController();
        aController.setModel(aModel);

        AController bController = new BController();
        bController.setModel(bModel);

        aModel.registreObserver(bController);
        bModel.registreObserver(aController);

        // Here the updates starts a notify b and b notify a and so on 
        aModel.notifyObservers();

    }
}

最佳答案

之所以出现无限循环,是因为每次更新 Observable 时,都会通知其观察者,但此通知过程会再次更新模型,如此重复。

以下是如何按照您想要的方式使用观察者模式的示例:

import java.util.Observable;
import java.util.Observer;

public class Example {

    public static void main(String[] args) {

        Model modelA = new Model();
        Model modelB = new Model();

        Observer aController = (observable, arg) -> {
            System.out.println("A controller: " + arg);
        };

        Observer bController = (observable, arg) -> {
            System.out.println("B controller: " + arg);
        };

        modelA.addObserver(bController);
        modelB.addObserver(aController);

        modelA.update("test");
        modelB.update("test2");
    }
}

class Model extends Observable {

    private String data;

    public void update(String data) {
        this.data = data;
        setChanged();
        notifyObservers(data);
    }
}

输出:

B Controller :测试

Controller :test2

关于java - 观察者模式无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37617427/

相关文章:

java - 我应该改变流中的对象吗?

c# - 在公共(public) API 中使用可空类型

c# - 单击按钮进入无限循环(ASP.Net)

java - 删除包含 next() 的 println 会导致无限循环?

mysql - SQL无限加载

java - 查找包含公共(public)字符的两个字符串的最快算法

java - Junit 测试用例中的代码可重用性

java - 使用java创建文件后,其中没有值

c# - 使用 REST API 的设计模式

c++ - 比工厂更好的设计模式?