torutkのブログ

ソフトウェア・エンジニアのブログ

イベントバスとリアクティブプログラミングの違いについて

GUIを持つアプリケーションの設計では、ソフトウェアアーキテクチャパターン*1としてMVCパターンを使用し、MVCパターンを実現する上で、Modelの変更をViewやControllerへ通知する仕組みにデザインパターン*2としてObserverパターンを使用するのが古典的定番です。

ところが、Observerパターンを使ったModelには、Observableのリストを管理し、状態変更の際にリストに登録されるObserbable全てに通知する仕組みを実装する必要があり、結構な作業となります*3

このModelからの通知をObserverパターンで実現する代わりに、イベントバスを使って実現すると、Modelの実装を簡潔にすることができます。Java SEではあまり事例を見かけませんが、Androidでは割とメジャーに使われているようです。

先日、Androidでイベントバスのライブラリを調べていたときに、非同期コールバック地獄から脱却する方法として、RxAndroid(RxJava)を使うという記事を見かけました。頭の片隅に留める程度にしていましたが、今度はJava SEで使うイベントバスライブラリを調べているときに、stackoverflowの次の記事が目にとまりました。

event handling - EventBus/PubSub vs (reactive extensions) RX with respect to code clarity in a single threaded application - Stack Overflow

内容を箇条書きで簡単にまとめると、

  • ScalaJavaFXでアプリケーションを作る際に、Observerパターンよりもイベントバスを好んで使っている
  • 最近リアクティブプログラミングを勉強したところ、Observerパターンを簡潔にする(callback hellを解消)とある
  • そこで、特にシングルスレッド環境ではイベントバスではなくRxJavaを使った方が実装が簡潔になるのでは?と気になった
  • RxJavaがイベントバスよりいいところは何ですか?

という投稿があり、そこにいろいろ回答が寄せられています。

  • scalafx(javafx)には独自のObservableがあるよ、scalafxのbindは簡単だよ
  • ReactFX調べてみたら
  • RxやReactFXのイベントストリームはイベントバスよりコードを明瞭にする。1)イベントバスはグローバルオブジェクト、2)イベントストリームにはイベントのfilter/transform/combineといった演算が用意されており、状態を隠蔽し、状態や副作用を減らすことができる
  • イベントバスではコンポーネントAとコンポーネントBを間接的に結合するので、接続が不明瞭。リアクティブなら、一箇所にa.events().subscribe(b::handle)と書くが、イベントバスではある場所でeventBus.register(b); 別な場所でeventBus.post(evt); と書く。

また、RxJavaを使ってEvent Busを実装するというブログがありました。
http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/

また、こんな記事も見かけました。
Reactive programming vs Event bus : androiddev

*1:MVCパターンは、書籍「ソフトウェアアーキテクチャ―ソフトウェア開発のためのパターン体系」(通称POSA本)でアーキテクチャパターンに分類される

*2:書籍「オブジェクト指向における再利用のためのデザインパターン」(通称GoF本)

*3:スレッドセーフに作成するには、Observableリストをコピーしてから通知するとか、CopyOnWriteArrayListを使うとか。Observableのインタフェースも用意するとか。