Break circular dependency with RxJava

When you need to split your code into different parts like in MVP, these different parts mostly have one to one dependency to each other. Like View needs Presenter and vice versa.

I am not saying circular dependency is a bad thing. I mean it can turned to be one way dependency by using RxJava.

Let’s say view needs to Presenter because it needs to call Presenter asynchronously such as button clicks:

class View {
private Presenter presenter;
  public void onClick(){
    presenter.onButtonClicked();
}
  public void showArticles(List<Article> articles){
//Set article list
}
}

And presenter needs view because it loads data and calls view asynchronously.

public class Presenter {
  private View view;

public void onButtonClicked(){
articleService.getArticleList()
.subscribe(new Action1<List<Article>>() {
@Override
public void call(List<Article> articles) {
view.showArticles(articles);
}
});
}
}

If we get asynchronous click events as an observable from the view, the view won’t need to call presenter’s button click method anymore.

public class View  {

public Observable<Void> buttonClicks() {
return RxView.clicks(button);
}

public void showArticles(List<Article> articles){
//Set article list
}
}

Here I used RxBinding library to get button clicks as observable. It just simply listen button clicks and produce observable packets for every click.

Now presenter only needs to listen these clicks to load articles.

public class Presenter {
private View view;
  public void listenButtonClicks() {
view.buttonClicks()
.flatMap(new Func1<Void, Observable<List<Article>>>() {
@Override
public Observable<List<Article>> call(Void aVoid) {
return articleService.getArticleList();
}
})
.subscribe(new Action1<List<Article>>() {
@Override
public void call(List<Article> articleList) {
view.showArticles(articleList);
}
});
}
}

We will get button clicks from the View and for every click it will get articles from service by using flatMap. So, view won’t need a presenter object anymore to call it’s methods. Simply view acts as provider for async events and Presenter consumes and calls view methods.

If you need to get asynchronous method calls from another object, you don’t need to always pass it as a dependency to the caller. You can get your events as an observable.