Programming

Deprecating the Observer pattern

Design Patterns Book

Pretty much every developer these days knows about the above book: Design Patterns, by the famous gang of four. Within the book, we find a lot of valuable information including the observer pattern. In this post, I will give a quick review of this pattern, show how it’s directly supported in Java, and why you shouldn’t really care, because it is considered deprecated. Though, it is kind of hard (as in impossible) to deprecate a pattern, and hence, it is really the typical implementations, like the ones found in the JDK and most older projects, which we can consider deprecated. In other words, if you think of applying the Observer pattern today, you may want to rethink the way you’re planning to do it after reading this post.

The Observer pattern

The wikipedia article gives the following definition for the pattern:

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

It’s an ok definition, but we will see throughout this article, why some of it isn’t really working out well. For those capable of the German language, it is interesting to note that the German wikipedia article refuses to give a concrete definition. It also manages to bring up the pros and cons, which sadly the English version doesn’t even address (as if there ever was something in computer science that didn’t involve a trade-off).

Java’s Observable and Observer

For now, let’s stick with the above definition and take a look at Java. In the java.util package we find a class Observable and an interface Observer, which correspond to the subject and observer in this definition, respectively. The Observable is a class that you are supposed to subclass, and which covers the responsibilities mentioned in the definition: it maintains the observers and provides means to notify them of a state change. “one of their methods” in Java’s Observer interface of course is reduced to the single method

void update(Observable o, Object arg)

If you check the documentation for the Observer or Observable you will see that they have been around for a while now. To be precise, they are about as old as Java itself and have been available since version 1.0. Yet, you don’t find them being used much. Why? Simply, because there are a lot of things wrong with it:

  1. Type-safety: Since, it has been around far longer than generics, we can see the infamous Object arguments. Having to fall back to the topmost type in your type system isn’t exactly what you should be fond of doing. So by using these classes, you will have to do a lot of casting and runtime type checking.
  2. Inheritance: Since the Observable is a class and you have no multiple inheritance in Java, you are severely limited in its usage. You must subclass your class from Observer, which in turn makes your concrete class an observer and gives it the responsibility to correctly call the Observer’s protected methods. As clean coders, we could argue favor composition over inheritance, or separation of concerns, but either way, this isn’t very good for reusability.
  3. Mutable state: You are supposed to mutate your observer object’s state, then call setChanged() and then either your object or someone else calls a notify method. There’s a heap of reasons why mutable state is a really bad choice (I might write another post on that one day). Interestingly, even the definition above includes “state changes”, which is also an implementational aspect of the pattern that I consider deprecated.
  4. Changed flag: not only is your own observable’s state mutable, but the Observable base class itself has a mutable flag that you have to use to mark your state as changed. This means, that everything, which causes your state to change (f.ex. every setter method) has to also call setChanged() in order to change the base class’ flag, as otherwise, no observers would be notified. This clearly will give you a lot of repetitive boilerplate code.
  5. Thread safety: When you call an observable’s notifyObservers() method, by default, the calling thread will be used to call each observer in turn and block until it’s update method has done its job. You have a choice in your subclass to outsource the notifications to threads in any way you like, but you also have to manually take care of the contract on the changed flag. Problems like being in the middle of notifying observers while getting another setChanged() call will quickly get overwhelmingly hard to solve cleanly.
  6. Notification responsibility: According to the above definition, the observable is responsible for notifying observers. In the Java class though, everyone who holds a reference to the Observable can initiate the notification. While the responsibility may lie with the observable, it is a strange API that also allows it to be moved to another place. And it certainly doesn’t make the above problem easier to solve when anyone could call the notify methods from outside.

The list could be continued, but I think I have made my point that it is probably not the best idea to rely on these java.util classes.

Application of the pattern

A simple application of this pattern occurs commonly in the model-view-controller concept. Your model becomes an observable subject and the view is an observer that is updated when notified of a changed value. Let’s look at a concrete example of the following observable book class:

public class Book extends Observable {
    private String author, title;
    private Integer year;

    public Book(String author, String title, Integer year) {
        this.author = author;
        this.title = title;
        this.year = year;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
        setChanged();
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
        setChanged();
    }

    public Integer getYear() {
        return year;
    }

    public void setYear(Integer year) {
        this.year = year;
        setChanged();
    }
}

We have a simple representation of a book here with just an author, title, and year of publication. You can see in line 1 that it is indeed an Observable, and how we have to add the boilerplate in the other highlighted lines to set the changed flag accordingly. Next, we would like to add an Observer to display the latest “state” of a Book object:

final Book mobyDick = new Book("Herman Melville", "Moby Dick", 1851);
mobyDick.addObserver((o,arg) ->
        System.out.println(((Book)o).getTitle() + " by " + ((Book)o).getAuthor()));

We can see the age of the Observer interface here again. Since, we have no generics, we have to cast the given observable into a Book again, and let’s better not even touch the arg Object. But hey, we’re now fully set up with a working implementation of the observer pattern – sort of. Let’s change our book into a comic book:

mobyDick.setAuthor("Olivier Jouvray, Pierre Alary");

Good thing we have an observer who gets notified. Oh right, we don’t get any notification just yet. It’s our job still to take care of that:

mobyDick.notifyObservers();

Now we will get the console printing to happen. Of course, we could have added the notifyObservers() call to our setters as well, but then what happens if you want to change the author and the year? We’d get two print outs instead.. bummer.

It’s about time to get this post turned around and look at how we can do things better.

Functional Reactive Programming

Since it’s initial appearance in 1997, functional reactive programming has been hiding in the academic shadows. Sometimes you could see it peak out a little, but it never really made a big impact until Microsoft (in particular Erik Meijer) came up with Reactive Extensions for .NET (Rx.NET). Meanwhile, it’s 2015 and we have ports for various programming languages: RxJava, RxJS, RxScala, RxClojure, RxCpp, Rx.rb, RxPY, RxKotlin, RxSwift, and others. It’s not like it is an easy thing to make these ports (in fact, it’s quite difficult as you can see from a youtube video about how RxScala tried various approaches that failed), but the power of functional reactive programming (FRP) is more than worth the effort.

The idea of “deprecating” the observer pattern has also been around for a while. Check out this paper from Ingo Maier and Martin Odersky on their take to deprecate the observer (with Scala.React, an academic library that seems to be completely neglectable in favor of RxScala).

The basic idea of FRP is based on Observables. Wherever you look for an introduction to the topic these days, you will encounter this table:

single items multiple items
synchronous T getData() Iterable<T> getData()
asynchronous Future<T> getData() Observable<T> getData()

This table really contains the essence of reactive programming. We start with the idea that we synchronously get a single item, i.e. a simple call to a getter method. When the request for data is supposed to return multiple items, then we synchronously block and the method instead returns an iterable (f.ex. a collection). During the last decade, blocking calls fell out of fashion though, since it’s kind of pointless to block your whole CPU core when you have a bunch of these that all would love to do your work for you. So, we all know about the Future, but as seen in the table, a future really is just a concept for returning a single item in an asynchronous fashion. Of course, you could get a Future of a collection, but that will still just be one answer. At one point in time, you have nothing, the moment after, you have the full collection. The observable is similarly asynchronous, but is a concept for returning multiple items. Not in one data-structure, but one after the other in a push-like fashion.

An Observable has three methods: onNext returns the next item, onCompleted is called once the observable has finished, and onError is used to propagate an error (and also implies termination).

RxJava example

With FRP you can create your own observables, and subscribe to them in order to be notified. Let’s first look at an example. We could re-define our Book class above, but to make the changes clearer, we create a new one called ObservableBook:

public class ObservableBook {
    private final String author;
    private final String title;
    private final Integer year;

    public ObservableBook(String author, String title, Integer year) {
        this.author = author;
        this.title = title;
        this.year = year;
    }

    public String getAuthor() {
        return author;
    }

    public String getTitle() {
        return title;
    }

    public Integer getYear() {
        return year;
    }
}

Notice how the class contains no indication whatsoever of what we are about to do with it. It’s just representing an immutable book. Apart from the name hinting at our intents, we find no trace of RxJava in this code yet. Since we want to be able to observe books, let’s create one and a corresponding observable:

final ObservableBook mobyDick = new ObservableBook("Herman Melville", "Moby Dick", 1851);
final rx.Observable<ObservableBook> observable = rx.Observable.from(Arrays.asList(mobyDick));

We can see the separation of concerns here: the book doesn’t know anything about being observed. It’s not as limiting as having to fix your base class in order to be observable. Or in other words, you can use RxJava to create observables of anything and everything, without having to change that thing you want to observe. When we now add our observer (or subscriber as it is referred to in RxJava), we can immediately see how type safety is back:

observable.subscribe(book -> System.out.println(book.getTitle() + " by " + book.getAuthor()));

And this already prints the output onto the console. Why? Because Rx Observables are distinguished between hot and cold ones. The one we created above was cold and became hot as soon as we subscribed to it.  We could subscribe another observer to it, and it would again become hot and send it our book. Other observables are always hot and subscribing to it means you only get the items that are being emitted after your subscription time.

You can also make observables, which continually emit items with no end in sight. The following example creates a ticker that will start emitting an ever increasing number every 10 milliseconds once you subscribe to it. It will also run in its own thread (you can similarly alter an Observable’s async behavior in whichever way you like by passing corresponding schedulers to the Observable methods), so that the second call may seem to do nothing if you omit the toBlocking call and your program exits immediately afterwards.

final rx.Observable<Long> ticker = rx.Observable.interval(10, TimeUnit.MILLISECONDS);
ticker.take(10).toBlocking().forEach(tick -> System.out.println("Tick: " + tick));

This example subscribes to the ticker with a special combinator method, that only takes the first 10 items (which will be the numbers 0 to 9) and then unsubscribes again. The result of the take(10) call is another Observable and the toBlocking() call ensures that the following forEach will be executed in the thread that executes this whole piece of code. In the end, we get the numbers 0 to 9 printed like this. This is truly quite a bit more involved than a simple loop, but there’s so much more to it than just counting:

  1. Re-Use: the ticker observable can be re-used any number of times. You can just add new subscribers to it and it will start ticking again.
  2. Async behavior is available. We can choose to use our current thread, or a ThreadPool or ExecutorService, or akka actors, …
  3. Resource cleaning: behind the scenes, we already have a complete resource cleaning system going. Once take(10) has received the 10 items, it unsubscribes from the ticker. The ticker in turn, will realize that there are no more subscribers and will itself shutdown and clean its resources. Similarly, once the forEach is done, it unsubscribes and the observable resulting from the take call knows it’s time to clean things up.
  4. Error handling: Even error handling is already included. No matter at which point an Observable fails, it will use its onError method to propagate that error down the call chain, such that you can address it (or not in the case of a forEach).

Replacing the traditional observer pattern

Let’s get back to our main topic though, and see how this Observable relates to the Observer pattern. The following class is a library class that can hold ObservableBook objects for us. We could derive the class from java.util.Observable now, keep a list of books, call setChanged and notifyObservers when a book is added and voila, traditional observer pattern. Instead, try to bend your mind around this:

public class Library {

    private final ReplaySubject<ObservableBook> onAdd = ReplaySubject.create();

    public void addBook(ObservableBook book) {
        onAdd.onNext(book);
    }

    public rx.Observable<ObservableBook> getBooks() {
        return onAdd;
    }
}

This class doesn’t even hold a list of books. It cannot possibly be a library, or can it?

final Library library = new Library();
library.getBooks().subscribe(book -> System.out.println(
        "New book: " + book.getTitle() + " by " + book.getAuthor()));

library.addBook(new ObservableBook("Herman Melville", "Moby Dick", 1851));
library.addBook(new ObservableBook("Olivier Jouvray, Pierre Alary", "Moby Dick", 2014));

library.getBooks().subscribe(book -> System.out.println("I like " + book.getTitle()));

In this sample, we first create a Library object, then we retrieve its Observable and subscribe to it. Nothing happens so far on the console, until we start adding two books via the library. Sure enough, the new books get printed to the console right there, but watch what happens when someone else subscribes to the same Observable. Both books will immediately be sent to that new subscriber as well and if we added a third book, both subscribers would get it. The list of books is still kept within the ReplaySubject, but just because we wanted it that way.

In a traditional observer pattern implementation your observers are more likely to just get notified in the future when something changes. If that is the behavior you wanted for the library, then switching the ReplaySubject for a PublishSubject is all you need to do. You would then get a Library class, which can notify everyone about new books being added, although that library would never contain any books itself, let alone know how many of them there are. Sounds stupid? Then exchange the Library for a Mouse and the books for MouseEvents.

Readdressing the definition

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

 

Let’s take another look at this definition. After all of this, we can see that the definition isn’t all that bad after all. FRP Observables maintain their dependents – we just call them subscribers – and they notify them. But the real problem is that “state change” in the case of functional reactive programming is completely undesirable. We want neither state nor change, but just to get notified of additional items. As subscribers we want to get to know that new book – it’s not about the library’s state being changed. If you use the PublishSubject mentioned above, the library wouldn’t even have any state related to books that could possibly change.

Summary

We have seen that RxJava, or FRP in general, closely relates to the observer pattern. We cannot truly deprecate the pattern, but we can recognize that FRP offers a solution to all the problems the observer pattern addressed and at the same time is much more powerful. In this post, I have just shown the tip of the iceberg. So much in fact, that I almost completely ignored the “F” of FRP, which is where most of the Observables’ power comes from. It isn’t until you start combining observables with higher-order functions (like the overly simplified interval example), that you really appreciate the difference between java.util.Observable and rx.Observable.