Reputation: 729
Suppose I have an event bus:
public class MessageEventBus {
private static MessageEventBus INSTANCE;
private PublishSubject<Message> bus = PublishSubject.create();
private MessageEventBus() {};
public static MessageEventBus instance() {
if (INSTANCE == null) {
INSTANCE = new MessageEventBus();
}
return INSTANCE;
}
public void send(Message message) {
bus.onNext(message);
}
public Observable<Message> toObservable() {
return bus;
}
public boolean hasObservers() {
return bus.hasObservers();
}
}
Inside an Android service, events are pushed to the bus:
MessageEventBus bus = MessageEventBus.instance();
Message message = new Message(userId, text);
if (bus.hasObservers()) {
bus.send(message);
return;
}
And here's the point (in a MVP presenter) where I attach an observer to the event bus:
MessageEventBus bus = MessageEventBus.instance();
bus.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(message -> {
if (message.userId == userId) {
view.messageReceived(message);
}
});
How do I move the if (message.userId == userId)
check from the presenter to the service? Or perhaps move that check to the event bus itself? Something like the following pseudocode in the service:
MessageEventBus bus = MessageEventBus.instance();
Message message = new Message(userId, text);
if (bus.hasObservers() && message.userId == theUserIdInThePresenter) {
bus.send(message);
}
Or in other words, how do I check if an observer attached to an observable meets some criteria before actually emitting that observable?
Upvotes: 0
Views: 282
Reputation: 1687
In Observer-Observable pattern, the Obsrvables should not care about the observers which subscribe to them. Their purpose is to emit data. However you can filter with more elegant way with filter operator. you have 2 possibilities:
1- put filter inside Presenter:
MessageEventBus bus = MessageEventBus.instance();
bus.toObservable()
.filter(message.userId == userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(message -> {
//you will only received message which match id
});
2- put filter inside service:
public class MessageEventBus {
private static MessageEventBus INSTANCE;
private PublishSubject<Message> bus = PublishSubject.create();
private MessageEventBus() {};
public static MessageEventBus instance() {
if (INSTANCE == null) {
INSTANCE = new MessageEventBus();
}
return INSTANCE;
}
public void send(Message message) {
bus.onNext(message);
}
//filter here
public Observable<Message> toFilteredObservable(int userId) {
return bus
.filter(message -> message.userId == userId)
;
}
public Observable<Message> toObservable() {
return bus;
}
public boolean hasObservers() {
return bus.hasObservers();
}
}
and call like this inside presenter:
bus.toFilteredObservable(int userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(message -> {
});
PS:if you want the observable to take care of observer criteria, you should implement manually the pattern.
Upvotes: 2