带有事件而不是参数的观察者模式(推送模型)

Observer Pattern with events instead of parameters (Push-Model)

现在我正试图完全理解观察者模式的概念。

据我了解(如有错误请指正): 如果你有不同的观察者需要一组不同的参数并且你不希望你的 updateFuntion 包含所有变量,建议使用事件而不是参数

=> updateFunction 中不必要的数据传输

=> updateFunction 需要多一个参数时出现问题(你必须更改所有观察者)

您能向我解释一下使用事件将如何解决这个问题以及它是如何实现的吗? (也许在 Java?)

假设我们有一个观察者接口定义了一个接受参数列表的方法,就像这样。

interface Observer {
    void doObserve(String name, String value);
}

然后,假设我们有一些 类 实现了该接口。

class ObserverA implements Observer {
    @Override
    public void doObserve(String name, String value) {
    }
}

class ObserverB implements Observer {
    @Override
    public void doObserve(String name, String value) {
    }
}

现在假设随着时间的推移,需求发生了变化,一些观察者需要了解一些额外的信息,例如“描述”。为了实现这个需求,我们不得不回过头来更改Observer中定义的方法签名,并更新所有实现该接口的类。

interface Observer {
    void doObserve(String name, String value, String description);
}

class ObserverA implements Observer {
    @Override
    public void doObserve(String name, String value, String description) {
    }
}

class ObserverB implements Observer {
    @Override
    public void doObserve(String name, String value, String description) {
    }
}

如果我们改为将这些参数分组到“事件”对象或“参数”对象中,那么我们就会将 Observer 接口与 类.

中的具体实现分离
class ObserverEvent {
    String name;
    String value;
    // getters/setters omitted for brevity
}

interface Observer {
    void doObserve(ObserverEvent event);
}

class ObserverA implements Observer {
    @Override
    public void doObserve(ObserverEvent event) {
    }
}

class ObserverB implements Observer {
    @Override
    public void doObserve(ObserverEvent event) {
    }
}

重现之前的场景,如果我们对描述字段有新的要求,那么我们可以简单地将其添加到 ObserverEvent 并可选择只修改关心使用的特定 类说明。

class ObserverEvent {
    String name;
    String value;
    String description;
}

这是一个小得多的代码更改。

在此示例中,代码更改都不是特别困难。在一个非常大的代码库中,虽然有许多 Observer 的实现,但像这样将参数与接口的方法签名解耦确实可以简化维护。例行代码更改不需要编辑那么多文件。方法签名不会爆炸成一个包含太多参数以致于难以阅读的列表。

我使用了 2 种可以结合使用的方法:

1) 使用特殊的上下文对象在观察者和可观察对象之间共享数据。您可以将数据放入上下文对象,将其传递给观察者并让他们更改其中的数据。被观察者通知的可观察对象读取上下文并使用该数据。例如,您有 observer-patterns 做一些工作。工作完成后,他们每个人都会通知可观察对象。 Observable 读取在构造函数级别注入观察者的共享上下文,并确定哪些资源现在可用于启动另一个作业。

2) 使用将成为 Notify() 方法参数的通知或事件 class。此事件对象具有 EventParams 属性 以供可观察对象读取。例如,当您的观察者引发进度事件 (ProgressEvent e) 时,您会阅读它的 e.EventArgs.Status 并根据需要使用。您可以为 ObserverEvent 和 ObserverEventParams 创建接口,并为每种事件实现它。在您的可观察 class 中,您仍然可以接受接口,然后使用责任链模式或类似的东西