EventBus / PubSub vs(反应扩展)RX在单线程应用程序中的代码清晰度 [英] EventBus/PubSub vs (reactive extensions) RX with respect to code clarity in a single threaded application

查看:389
本文介绍了EventBus / PubSub vs(反应扩展)RX在单线程应用程序中的代码清晰度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在使用EventBus / PubSub 体系结构/模式与Scala(和JavaFX)实现一个简单的笔记组织应用程序(类似于一个Evernote客户端与一些添加的思维导图功能),我不得不说,我真的很喜欢EventBus在观察者模式。



以下是一些EventBus库:



https://code.google.com/p/guava-libraries/wiki/EventBusExplained



http://eventbus.org (目前似乎是down)这是我正在使用的我的实现。



http://greenrobot.github。 io / EventBus /



以下是EventBus库的比较: http://codeblock.engio.net/37/



EventBus与发布订阅模式



不过!



最近,我采取了 Coursera的反应过程,并开始怀疑是否使用 RXJava 而不是EventBus来简化事件在单线程应用程序中更好地处理代码?



我想问一下使用这两种技术编程的人的体验的eventbus库某种形式的无效扩展(RX)):是否更容易使用RX来处理事件处理复杂性,而不是使用事件总线架构,因为不需要使用多线程



我问这个是因为我在 Coursera的活动讲座 RX 导致比使用观察者模式更清晰的代码(即没有回调地狱),但是我没有发现EventBus架构与 RXJava 之间的任何比较。所以很明显,EventBus和RXJava都比观察者模式更好,但是在代码清晰度和可维护性方面,单一的线程应用程序更好?



如果我理解正确, RXJava 的主要卖点是可以用于制作响应式应用程序如果有阻塞操作(例如等待服务器的响应)。



但是我根本不关心非同步性,所有我关心的是保持代码清理在单线程应用程序中解开和容易理解。



在这种情况下,使用RXJava比EventBus还好吗?



我认为EventBus将是一个更简单和更干净的解决方案,我没有看到任何理由为什么我应该使用RXJava进行单线程应用程序赞成一个简单的EventBus架构。



但可能是错误的



如果我错了,请更正我并解释为什么RXJava会比一个简单的EventBus更好,在单线程应用程序的情况下,不执行阻塞操作。

解决方案

以下是我在单线程同步应用程序中使用反应事件流的好处。



1。更多的声明性,较少的副作用和较少的可变状态。



事件流能够封装逻辑和状态,潜在地使您的代码没有副作用和可变变量。 / p>

考虑一个应用程序来计算按钮点击次数,并显示点击次数作为标签。



平原JavaFX解决方案:

  private int counter = 0; //可变字段!!! 

按钮incBtn = new Button(Increment);
标签label = new Label(0);

incBtn.addEventHandler(ACTION,a - > {
label.setText(Integer.toString(++ counter)); // side-effect !!!
} );

ReactFX解决方案:

 按钮incBtn = new Button(Increment); 
标签label = new Label(0);

EventStreams.eventsOf(incBtn,ACTION)
.accumulate(0,(n,a) - > n + 1)
.map(Object :: toString)
.feedTo(label.textProperty());

不使用可变变量,对 label.textProperty进行副作用分配()隐藏在抽象背后。



在他的硕士论文中, Eugen Kiss 已经提出了ReactFX与Scala的集成。使用他的集成,解决方案可能如下所示:

  val incBtn = new Button(Increment)
val label = new Label(0)

label.text | = EventStreams.eventsOf(incBtn,ACTION)
.accumulate(0,(n,a)=> n + 1 )
.map(n => n.toString)

相当于以前,除了控制控制的反转还有其他的好处。



2。意味着消除故障和冗余计算。 (仅限ReactFX)



毛刺是可观察状态的暂时不一致。 ReactFX具有暂停事件传播的手段,直到对对象的所有更新都进行了处理,避免了毛刺和冗余更新。具体来说,请查看可暂停事件流指标 InhiBeans 我关于InhiBeans的博文。这些技术依赖于事件传播是同步的,因此不会转换为rxJava。



3。清除事件生成器和事件消费者之间的连接。



事件总线是任何人都可以发布和订阅的全局对象。事件制作者和事件消费者之间的联系是间接的,因此不太清楚。
对于反应事件流,生产者和消费者之间的联系更加明确。比较:



活动总线

  class A {
public void f(){
eventBus.post(evt);
}
}

//初始化期间
eventBus.register(consumer);
A a = new A();

a 和<$ c之间的关系$ c>消费者从初始化代码看不清楚。



事件流:

  class A {
public EventStream&MyEvent>事件(){/ * ... * /}
}

//初始化期间
A a = new A();
a.events()。subscribe(consumer);

a 和<$ c之间的关系$ c> consumer 非常明确。



4。一个对象发布的事件表现在其API中。



使用上一节中的示例,在事件总线示例中, A 的API不会告诉您由 A 的实例发布的事件。另一方面,在事件流示例中, A 的API指出 A 的实例发布类型的事件 MyEvent


Currently, I am using an EventBus/PubSub architecture/pattern with Scala (and JavaFX) to implement a simple note organizing app (sort of like an Evernote client with some added mind mapping functionality) and I have to say that I really like EventBus over the observer pattern.

Here are some EventBus libraries :

https://code.google.com/p/guava-libraries/wiki/EventBusExplained

http://eventbus.org (currently seems to be down) this is the one I am using in my implementation.

http://greenrobot.github.io/EventBus/

Here is a comparison of EventBus libraries : http://codeblock.engio.net/37/

EventBus is related to the publish-subscribe pattern.

However !

Recently, I took the Reactive course by Coursera and started to wonder whether using RXJava instead of EventBus would simplify the event handling code even more in a single threaded application ?

I would like to ask about the experiences of people who programmed using both technologies (some kind of eventbus library and some form of the reactive extensions (RX)): was it easier to tackle event handling complexity using RX than with an event bus architecture given that there was no need to use multiple threads ?

I am asking this because I have heard in the Reactive Lectures on Coursera that RX leads to much cleaner code than using the observer pattern (i.e. there is no "callback hell"), however I did not find any comparison between EventBus architecture vs RXJava. So it's clear that both EventBus and RXJava are better than the observer pattern but which is better in a single threaded applications in terms of code clarity and maintainability ?

If I understand correctly the main selling point of RXJava is that it can be used to produce responsive applications if there are blocking operations (e.g. waiting for response from a server).

But I don't care about asychronicity at all, all I care about is keeping the code clean, untangled and easy to reason about in a single threaded application.

In that case, is it still better to use RXJava than EventBus ?

I think EventBus would be a simpler and cleaner solution and I don't see any reason why I should use RXJava for a single threaded application in favour of a simple EventBus architecture.

But I might be wrong!

Please correct me if I am wrong and explain why RXJava would be better than a simple EventBus in case of a single threaded application where no blocking operations are carried out.

解决方案

The following is what I see as benefits of using reactive event streams in a single-threaded synchronous application.

1. More declarative, less side-effects and less mutable state.

Event streams are capable of encapsulating logic and state, potentially leaving your code without side-effects and mutable variables.

Consider an application that counts button clicks and displays the number of clicks as a label.

Plain JavaFX solution:

private int counter = 0; // mutable field!!!

Button incBtn = new Button("Increment");
Label label = new Label("0");

incBtn.addEventHandler(ACTION, a -> {
    label.setText(Integer.toString(++counter)); // side-effect!!!
});

ReactFX solution:

Button incBtn = new Button("Increment");
Label label = new Label("0");

EventStreams.eventsOf(incBtn, ACTION)
        .accumulate(0, (n, a) -> n + 1)
        .map(Object::toString)
        .feedTo(label.textProperty());

No mutable variable is used and the side-effectful assignment to label.textProperty() is hidden behind an abstraction.

In his master thesis, Eugen Kiss has proposed integration of ReactFX with Scala. Using his integration, the solution could look like this:

val incBtn = new Button("Increment")
val label = new Label("0")

label.text |= EventStreams.eventsOf(incBtn, ACTION)
    .accumulate(0, (n, a) => n + 1)
    .map(n => n.toString)

It is equivalent to the previous, with the additional benefit of eliminating inversion of control.

2. Means to eliminate glitches and redundant computations. (ReactFX only)

Glitches are temporary inconsistencies in observable state. ReactFX has means to suspend event propagation until all updates to an object have been processed, avoiding both glitches and redundant updates. In particular, have a look at suspendable event streams, Indicator, InhiBeans and my blog post about InhiBeans. These techniques rely on the fact that event propagation is synchronous, therefore do not translate to rxJava.

3. Clear connection between event producer and event consumer.

Event bus is a global object that anyone can publish to and subscribe to. The coupling between event producer and event consumer is indirect and therefore less clear. With reactive event streams, the coupling between producer and consumer is much more explicit. Compare:

Event bus:

class A {
    public void f() {
        eventBus.post(evt);
    }
}

// during initialization
eventBus.register(consumer);
A a = new A();

The relationship between a and consumer is not clear from looking at just the initialization code.

Event streams:

class A {
    public EventStream<MyEvent> events() { /* ... */ }
}

// during initialization
A a = new A();
a.events().subscribe(consumer);

The relationship between a and consumer is very explicit.

4. Events published by an object are manifested in its API.

Using the example from the previous section, in the event bus sample, A's API does not tell you what events are published by instances of A. On the other hand, in the event streams sample, A's API states that instances of A publish events of type MyEvent.

这篇关于EventBus / PubSub vs(反应扩展)RX在单线程应用程序中的代码清晰度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆