【问题标题】:Working with observer pattern使用观察者模式
【发布时间】:2017-09-17 19:23:14
【问题描述】:

我在下面有一个观察者类。我的问题是我怎样才能设置这个类来听(观察)一个以上的主题?

    public class Observer2 implements Observer {
      private Subject robot;


      public Observer2(Subject robot){
       this.robot = robot;
       robot.registerObserver(this);
    }

      @Override
      public void update(){}
}

【问题讨论】:

  • 将 2 Subjects 传递给构造函数,并注册两者。
  • 或者换句话说,如果您知道如何观察一个人,那么对其他人也这样做。
  • 如果我通过了 2 个科目,那是否意味着我总是必须观察超过 1 个科目?您的意思是公共观察者2(主题 r,主题 r){}?

标签: java observer-pattern


【解决方案1】:

你可以有一个 Subject 类,它将所有观察者存储在一个列表中。

public abstract class Subject
{
    private ArrayList<Observer> observerList = new ArrayList<>();

    public void attach(Observer observer)
    {
        observerList.add(observer);
    }

    /**
     * Notifies observers to run execute
     */
    protected void notifyObservers()
    {
        for(int i = 0; i < observerList.size(); i++)
        {
            observerList.get(i).update();
        }
    }
}

典型的观察者界面:

interface Observer
{
    void update();
}

之后,您可以使用notifyObservers() 方法触发观察者。

【讨论】:

  • 我有这个,只是没有放在这里。我只是想知道如何让我的一位观察者观察多个主题
【解决方案2】:

使用一组。

public class MultiObserver extends Observer {
    private final Set<Subject> observed = new HashSet<>();

    public void observe(Subject s) {
        if (observed.add(s))
            s.registerObserver(this);
    }
}

【讨论】:

    【解决方案3】:

    使用 Java 的 ObserverObservable,它们是为正确处理多个主题而设置的:

    class Robot extends Observable {
        public void act() {
            notifyObservers("Run!");
        }
    }
    class Cyborg extends Observable {
        public void act() {
            notifyObservers("Hide!");
        }
    }
    
    public class MyObserver implements Observer {
        @Override
        public void update(Observable subj, Object arg) {
            if (subj instanceof Robot) {
                System.out.println("Scary robot says " + arg);
            } else if (subj instanceof Cyborg) {
                System.out.println("Lovely cyborg says " + arg);
            } else {
                System.out.println("What's this? " + arg);
            }
        }
    }
    

    注册方式不同:

    // Construct observables
    Robot r = new Robot();
    Cyborg c = new Cyborg();
    // Add observer to both of them
    MyObserver o = new MyObserver();
    r.addObserver(o);
    c.addObserver(o);
    r.act();
    c.act();
    

    【讨论】:

    • 为此我必须有两个可观察的类?我只是希望观察者能够观察另一个主题,如果我将来添加一个。
    【解决方案4】:

    ConcreteObserver 可以观察多个 Subject,只需多次调用 Subject 提供的 attach 方法。
    如果问题是:

    “ConcreteObserver 如何观察许多具有不同状态的不同种类的 ConcreteSubjects?”

    答案是,在 ConcreteObserver 中,update 方法必须重载以管理多次等于 ConcreteObserver 必须观察的状态类型。
    ConcreteObserver 还必须有一个状态数组来存储观察到的 Subjects 状态,并有一些机制来避免来自不同 Subject 的相同类型的状态影响彼此的状态。

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 2023-04-10
      • 1970-01-01
      • 2013-03-05
      • 2016-05-11
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多