首页 > 解决方案 > 如何使用 Java 10 中的 Flow API 来替换 Observable/Observer 代码(最好不使用多线程)?

问题描述

我最近将我的项目从 Java 8 升级到了 Java 10,并且收到了很多警告说 Observer 和 Observable 现在已被弃用。替换它们的建议是 Flow API - 问题是我还没有找到一个关于如何为 Flow API 编码的像样的教程。我发现的所有内容都表明不直接实现发布者/订阅者,而且我发现的大部分内容表明 Flow API 很大程度上基于多线程。

注意:我已经在 StackOverflow 以及 Quora 和其他一些网站上找到了这个答案,并且有几个人引用 Observable 对象不能被序列化,这是完全不真实的,因为我为我的每个 bean 和许多我的其他类也是如此,甚至已经序列化以归档我的一些对象并将它们从文件中读回对象形式。

但是,多线程是一个问题——在响应模型对象的更改时,我不想使用流或多线程。问题 1 是 - 这是使用 Flow API 的绝对要求,还是有另一组不需要多线程和流​​的类/接口?

在查看 Flow.publisher 的 javadocs 时,我认为这将是我将 Observable 替换为 - 因为它是一个接口,这意味着我想我必须放置(类似于我的 ListModel 和 TableModel 类实现)一组订阅者(类似于观察者??)并放置自定义代码以从我的发布者中添加和删除它们?问题 2 - 我有这个权利吗?

问题 3.) Flow.Publisher 和 Flow.Subscriber 中的泛型类型参数是什么?它显示了一个类型,但我不知道该类型在哪里使用 - 我将在这里为我的一个模型类放置代码:

package net.draconia.frenchstudy.model;

import java.io.Serializable;

import java.util.concurrent.Flow.Publisher;
import java.util.concurrent.Flow.Subscriber;

public class Category implements Publisher<Category>, Serializable
{
    private static final long serialVersionUID = 5281400324476454101L;

    public static final Category EMPTY_CATEGORY = new Category(); 

    private Integer miId;
    private String msCategory;

    public Category()
    { }

    public Category(final int iId)
    {
        setId(iId);
    }

    public Category(final String sCategory)
    {
        setCategory(sCategory);
    }

    public Category(final int iId, final String sCategory)
    {
        setId(iId);
        setCategory(sCategory);
    }

    public String getCategory()
    {
        if(msCategory == null)
            msCategory = "";

        return(msCategory);
    }

    public int getId()
    {
        if((miId == null) || (miId < 0))
            miId = 0;

        return(miId);
    }

    public void setCategory(final String sCategory)
    {
        if(sCategory == null)
            msCategory = "";
        else
            msCategory = sCategory;

        setChanged();
        notifyObservers();
    }

    public void setId(final Integer iId)
    {
        if((iId == null) || (iId < 0))
            miId = 0;
        else
            miId = iId;

        setChanged();
        notifyObservers();
    }

    public void subscribe(final Subscriber<? super Category> subscriber)
    {

    }

    public String toString()
    {
        return(getCategory());
    }
}

当我试图用 Flow.Publisher 替换 Observable 但不知道在订阅方法代码中放置什么时,它被部分混蛋了。我对泛型类型进行了疯狂的猜测,它与正在使用的类的类型相同,但我不确定这是否正确。

我一直很擅长将逻辑放在各种观察者中,以处理 Observable 对象中的 1 个可能的更改,并将其他更改留给其他观察者 - 所述观察者的执行顺序对我来说并不重要,因为我在编写代码时考虑到了这一点它不会依赖于一个在另一个之前或之后执行。我从来没有注意到由于观​​察者在许多情况下执行不止一次而导致执行速度的任何降低,所以这对于 Oracle 的决定来说似乎是愚蠢的,但我仍然想知道 - 我如何使用 Flow API 来替换 Observable/Observer我的程序中的代码?或者如果它不能那样工作,那么我可以使用什么,因为我已经看到了使用 PropertyChangeListeners 的可能解决方案,但我的模型对象不是属性,我没有 我不想定义属性(从未使用过 PropertyChangeListener,所以我也不确定它们是如何工作的),因为如果我必须定义它们,那么在数十个模型对象中,如果不是接近一千个属性来定义它们,它们将超过数百个。任何指向教程、代码或示例的链接都会有所帮助。

标签: javaobservableobserver-patternjava-10

解决方案


推荐阅读