【问题标题】:How observers subscribe on observables?观察者如何订阅可观察对象?
【发布时间】:2017-12-03 00:49:02
【问题描述】:

我读过一本名为“Head First Pattern”的书,并且有一个关于“观察者”模式的问题。

如果观察者的 API 只包含 1 个方法“update()”,观察者应该如何订阅 observable?

首先,我假设观察者必须包含方法“subscribe(Observable observable)”

如何以最佳方式实现订阅机制?

【问题讨论】:

标签: java


【解决方案1】:

实际上,恰恰相反。您将Observer 附加或添加到将被观察的对象Observable。您这样做是为了让被观察对象在其状态发生变化后能够notify 观察者。

在这种模式中,如果您要在观察者对象中订阅 Subject 并且只这样做。观察者如何知道在动作发生的那一刻主体的状态何时改变?也许观察者可以开始轮询并询问主题的状态,直到它发生变化,然后观察者会对其采取行动。但这远非理想。

这就是WatchService 所发生的情况,例如,您将文件添加到服务以便在文件被修改后得到通知。粗略地说,您正在“订阅”观察者中的主题。但是在这里,您启动了一项服务,该服务将在幕后处理您所需要的。

无论如何,在您的情况下,最好的方法是让主题对象管理观察者并在适当的时候调用它。

查看此链接: https://sourcemaking.com/design_patterns/observer

您必须实现您的类Subject,以便它接收将观察其行为并根据需要得到通知的实体。这是Subject's 当进行所需的更改时,对notify 观察员负责。

Java 有自己的模式实现。您应该首先阅读Observable 类以了解其要点。然后,您应该按照已阅读的指南实施自己的指南。思路是这样的:

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

public class TestObserver {
    public static void main(String[] args) {
        Subject subject = new Subject();
        ContentObserver contentObs = new ContentObserver();
        subject.addObserver(contentObs);
        // Once you call setContent, the object contentObs
        // will be notified and print the desired text
        subject.setContent("test");
    }
}

class Subject {

    private String content;

    private List<ContentObserver> observers = new ArrayList<>();

    public void addObserver(ContentObserver obs) {
        observers.add(obs);
    }

    public void setContent(String content) {
        this.content = content;
        notifyContentObservers();
    }

    private void notifyContentObservers() {
        observers.forEach(obs -> obs.update(content));
    }

}

class ContentObserver {

    public void update(String content) {
        System.out.println("Content was changed! New content = " + content);
    }

}

请记住,这是一个示例。你必须通过添加、删除等方式来管理你的观察者。code to an interface也是可取的,所以你应该根据你要观察的内容创建自己的Observer接口。

此外,您不应使用 java 提供的实现,因为它在 java 9 中已被弃用: https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html https://dzone.com/articles/javas-observer-and-observable-are-deprecated-in-jd

如果您想要更可靠和更被动的东西。看一眼: https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html

干杯!

【讨论】:

  • 谢谢!我只是想知道为什么“ContentObserver”没有“订阅”方法?一个对象如果想成为任何 Subject 的观察者应该怎么做?
  • 应该加入到Subject的观察者列表中。例如,在我的示例中,通过此调用:subject.addObserver(contentObs)
  • 是的。但遵循该模式是否可以向观察者添加类似于 subscribe(Subject s) {s.addObserver(this);} 的方法?
  • 哦!我明白你了现在!这样做的问题是,如果您在观察者中订阅主题并且只这样做。观察者如何知道主体的状态何时改变?如果观察者是管理主题的响应者,如果主题没有通知观察者的方法,他将永远不会收到通知。我现在说清楚了吗?我想我明白你在想什么。
  • 我已经编辑了我的答案并扩展了解释。看看,告诉我你的想法。干杯!
【解决方案2】:
 observable.addObserver(observer);
 // now when observable changes, the observer will know

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-26
    • 2011-06-17
    • 2019-03-28
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多