如何使用Java 10中的Flow API替换Observable / Observer代码(最好不使用多线程)?

Set*_*mer 5 java observable observer-pattern java-10

最近,我将我的项目从Java 8升级到Java 10,并发出了很多警告,指出现在不推荐使用Observer和Observable。替换它们的建议是Flow API-问题是我尚未找到有关如何为Flow API编写代码的不错的教程。我发现的所有内容都说不能直接实现发布者/订阅者,而且我发现的许多内容都表明Flow API很大程度上基于多线程。

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

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

在查看Flow.publisher的javadocs时,我将用Observable替换-因为这是一个接口,这意味着我想我必须放入(类似于ListModel和TableModel类的实现)订阅者集合(类似于Observers?),并放置自定义代码以将其添加到我的发布商中或从中删除?问题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());
    }
}
Run Code Online (Sandbox Code Playgroud)

当我试图用Flow.Publisher替换Observable时,它部分被混为一谈,但是不知道在subscribe方法代码中应该放什么。我对通用类型与正在使用的类相同的类型进行了大胆的猜测,但是我不确定这是否正确。

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