Showing posts with label pattern: Observer. Show all posts
Showing posts with label pattern: Observer. Show all posts

January 10, 2012

Observer: Part IV - Generic Observer

This is continuation from Observer: Part III - Java EventListenerList.

Sorry for the delay. I ditched the original ending for this series and did not have time to write a new one until now. I was planning to finish by presenting you generic versions of the original Java Observer/Observable and teaching how to use them. But I changed my mind, since the interesting part about generic observer is not how to use it, but how to write it. And that is the main issue today.


Warning for the beginners! 

If you have been reading through the previous parts and are here to learn how to use the observer pattern, the generic observer is not really the best way. You are better off by sticking to the stuff that you can find in the previous parts. While making the pattern implementation generic does solve some of it's problems, it does not change the fact that the Observer is a concrete class that you have to inherit. Also, you would need to take these classes into your own code base, to keep and take care for the rest of your application's life.

Experience is about knowing when it's best to keep things simple, and when it's worth to drive for a perfect solution that is often more complex. We are dealing with a simple pattern here, why not keep the solution simple too?


You have been warned. The perverts who want The Perfect Observer Pattern may continue...

If you really, really want to bring in some complex stuff to your code-base, there is even MORE complicated solution you can use for the observer pattern. In his blog, Steven Jeuris's has solved the same problem by using dynamic proxies. The solution is beautiful and uses both generics and reflection. Just a type of thing your average maintenance person is going to loooove! Just don't use it in performance-critical places as doing things through reflection is quite slow.

Steven also promotes PerfectJPattern that has generic implementations for several design patterns. Each pattern  is nicely explained with code examples, see the Observer, for example. I just stumbled into that, but it might be interesting to check how it does things and if it's good, maybe run it through the legality checks to see if it's published under a licence that the company I work with would allow. Most big companies cannot just allow you to bring in new third-party libraries without legality-check. The reason is that some open-source licences make their user applications open-source too.


Prerequisites

While the previous parts of this series have been beginner-level, this one is not. It's not that this would be much harder to understand, just that you need some background information. So if you are a beginner, I suggest that you go through this Java lesson on Generics before continuing.

If you are an expert in generics, you are going to have some good laughs on my behalf.

If you just stumbled in without reading the previous parts, you might want to check the Java implementation of the Observer interface and an Observable class to go with the interface. Those are the classes that we are rewriting here.

Are you ready? Let's start.


Defining the signature

When you start designing generic classes, it's always best to begin by thinking about their signatures. In this case the question is - how many generic arguments do we need here?

Fortunately, the answer can be found in the book Java Generics and Collections, page 137. It gives us the following signatures:

public class Observable<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>

public interface Observer<S extends Observable<S, O, A>, O extends Observer<S, O, A>, A>

That is nice.... huh? S stands for Subject, O for Observer and A as Argument.

It does come with a warning: "So you might wonder: could the declarations be simplified by dropping the type parameter S from Observable and the type parameter O from Observer? But this won't work, since you need S to be in scope in Observable so that it can be passed as a parameter to Observer, and you need O to be in scope in Observer so that it can be passed as a parameter to Observable".

I guess I should have read the first 137 pages also, but I was just googling around and I did not understand the warning. There was no further explanation and I did not see any obvious reason why the extended classes should be in scope. So my little caveman brain told me: "Me more smart, me does this better, more simple".

What IF we try to do this with one generic argument only? That would give us the following signatures:

public class Observable<A>

public interface Observer<S extends Observable<A>, A>

Yeah, yeah, I know it won't work, but let's just play we don't know it yet.


Trying out with one generic argument

Here is the signature for Observer's update method:

void update(S observable, A arg);

At the same time Observable would manage its Observers like this:

public void addObserver(final Observer<? extends Observable<A>, A> observer)

As we implement our Observable we will stumble into a problem in notifyObservers(A arg) method. We need to call the update(S observable, A arg) method of the Observer, but it does not accept our Observable as an argument. Why not, the definition for S was <S extends Observable<A>>? Typing is very strict in generics and the Observer wants something that extends the Observable. Observable extends Object, so based on the generics rules it is not valid argument for update method. I have not yet found syntax in generics for saying: "<? extends Something, but Something will do too>", and that problem actually does not go away by adding more generic arguments. So I just ended up using plain, non-typed Observer in notifyObservers(A arg) method in order to be able to pass Observable.this as an argument.

But this little incident draws our attention to typing. Our Observer accepts items that are of type <? extends Observable<A>>. So is it possible that we end up passing incompatible argument to update method? Actually, in this one generic argument solution, it is. Take a look at this:

    public class Koala extends Observable<Boolean> {

        public void setHungry(final boolean isHungry) {
            setChanged();
            notifyObservers(isHungry);
        }

        @Override
        public String toString() {
            return "koala";
        }
    }

    public class Tiger extends Observable<Boolean> {

        public void setAngry(final boolean isAngry) {
            setChanged();
            notifyObservers(isAngry);
        }

        @Override
        public String toString() {
            return "tiger";
        }
    }

    public interface KoalaObserver extends Observer<Koala, Boolean> {

    }

And here is our test case that shows the problem:

    public void testMixedObservers() {
        final Tiger tiger = new Tiger();
        final KoalaObserver koalaObserver = new ZooKeeper();

        tiger.addObserver(koalaObserver);
        try {
            tiger.setAngry(true);
        }
        catch (final ClassCastException ex) {
            assertEquals(
                    "org.beyondhc.lessons.observer.genericwithonearg.GenericObserverTest$Tiger"
                            + " cannot be cast to "
                            + "org.beyondhc.lessons.observer.genericwithonearg.GenericObserverTest$Koala",
                    ex.getLocalizedMessage());
        }

    }

As you can see, we can add KoalaObserver to Tiger. Tiger will happily accept any Observer that extends Observable<Boolean>. As we cannot check for the correct type, we get an ugly ClassCastException. This is definitely to the worse from the original solution. It is clear now what the warning in the book meant - unless the Observer knows the Observable and vice versa, we cannot be sure that the user does not make similar mistakes than with the non-typed variants. Although I was not able to repeat this particular problem with a version that uses two generic arguments, I am pretty sure someone smarter than me can get it broken too. Thus, let's forget trying this with less arguments and return to the three-argument version.


Observable and Observer with 3 generic arguments

When the signatures are set, the rest of the implementation is not that hard. But the signature does look complex, so you might be wondering about the usage. And doesn't it make this thingy really non-flexible if Observable is so tightly coupled with its Observer?

It turns out that this tight coupling actually forces you to better design. First, it makes it more tempting to implement a separate interface for the Observer:

public interface TigerObserver extends
            Observer<Tiger, TigerObserver, Boolean> {

    }

And secondly, as the Observer can implement only one interface, you are forced to composition if you want to observe more than one type of items:

    public class ImprovedZooKeeper {

        private final TigerObserver tigerObserver;

        public ImprovedZooKeeper() {
            this.tigerObserver = new TigerObserver() {

                @Override
                public void update(final Tiger observable, final Boolean arg) {
                    // Do your actions here
                }
            };
        }

        public void observerTiger(final Tiger tiger) {
            tiger.addObserver(tigerObserver);
        }

    }

And the composition effectively hides the update method so that only Tiger may call it.

The Observer and Observable discussed in this article can be found in the BeyondHc util package.

The broken ones with 1 and 2 generic arguments are available too. They can be found on the test side of the BeyondHc, in packages
observer.genericwithonearg
and
observer.genericwithtwoargs.





November 06, 2011

Observer: Part III - Java EventListenerList

This is continuation from Observer: Part II - Degenerated Observer.

In the previous parts, I have shown you how you may break your code by using Observer Pattern implementation that comes along in Java. I have also shown you how you can use a degenerated form of Observer Pattern.

Today I am going to show you yet another way to implement this pattern. I hope you are not getting tired of koalas, since we are about to implement our Koala Zoo example again. This time we are about to use javax.swing.event.EventListenerList.


Do it better - Use EventListenerList

Even though EventListenerList is located in javax.swing.event package, it is in no way restricted to user interface usage. Unlike the Java Observable/Observer, using the EventListenerList does not lead to fragile code either. You can find the EventListenerList usage instructions in the header of it's API documentation. It's almost as old as the Observable/Observer, but still useful today. So go ahead and use it!

Let's implement our Koala again:
    public class Koala {
        private final EventListenerList observers = new EventListenerList();

        public void addKoalaListener(final KoalaObserver observer) {
            observers.add(KoalaObserver.class, observer);
        }

        public void removeKoalaListener(final KoalaObserver observer) {
            observers.remove(KoalaObserver.class, observer);
        }

        public void setHungry(final boolean isHungry) {
            final KoalaEvent event = new KoalaEvent(isHungry);
            fireKoalaChanged(event);
        }

        private void fireKoalaChanged(final KoalaEvent event) {
            // Guaranteed to return a non-null array
            final Object[] listeners = observers.getListenerList();
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length - 2; i >= 0; i -= 2) {
                if (listeners[i] == KoalaObserver.class) {

                    ((KoalaObserver) listeners[i + 1]).koalaUpdate(this, event);
                }
            }
        }

        @Override
        public String toString() {
            return "koala";
        }
    }

Now the Koala keeps it's observers stored in the EventListenerList. Whenever changes happen, it notifies the observers.

But what is up with the funny backwards loop that skips every other element? 

Well, that is taken directly from the usage instructions in the API. The getListenerList returns an array that contains ListenerType-Listener pairs. So the first element in the list will be the type of the listener, e.g. KoalaObserver.class, and the second element will be the actual listener.

There only reason that I know for backwards looping is that this thingy was originally written for the Swing Events. The event handling has some rules and one of them is that the last registered listener should be notified first. That way the newly added listeners have possibility to consume events, too. Thus, the list must be processed from the back to the start.

There are some suggestions about other reasons in this StackOverflow thread: Why is EventListenerList traversed backwards in fireFooXXX(), but I am not buying most of those. The listener array is not going to break or anything if you loop it forwards.

But let's get back to Koala Zoo.

The KoalaObserver now uses a new KoalaEvent, but otherwise is has stayed the same:
    public interface KoalaObserver extends EventListener {
        void koalaUpdate(Koala koala, KoalaEvent change);
    }

I kept the KoalaObserver interface name the same as in previous implementation, so you can compare these easily. But normally I would have called it the KoalaListener.

The KoalaEvent looks like this:
    public class KoalaEvent {

        private final boolean hungry;

        public KoalaEvent(final boolean isHungry) {
            this.hungry = isHungry;
        }

        public boolean isHungry() {
            return hungry;
        }

    }

Note how the KoalaEvent hungry field is defined final. It should be up to the Koala to decide whether it is hungry or not, so we do not want anyone to change that field value later. Always, if possible, try to make your classes immutable. For non-english-speakers, immutable means not modifiable, something that you cannot change after it has been created.

I added the KoalaEvent just to demonstrate how you can deliver complex change information. Using event class is not mandatory. We could have just passed a boolean parameter in the koalaUpdate method.

Here is our ZooKeeper:
    public class ZooKeeper implements KoalaObserver {

        @Override
        public void koalaUpdate(final Koala koala, final KoalaEvent change) {
            if (change.isHungry()) {
                LOGGER.info("Oh, the " + koala
                        + " is hungry. It needs some eucalyptus.");
            }
        }

    }

While handling the events, keep in mind that you do not know who else is going to get them after you are done. So never make any changes to the events that you handle. Exception to this rule is "consuming" the events, like key presses, so that the listeners that come next know that application has already acted based on user input. Most of the events should be immutable, so you can not change them even if you wanted.

And here we test that the notification is sent:
    public void testKoalaGetsFood() {
        final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
        final Koala koala = new Koala();
        final ZooKeeper zooKeeper = new ZooKeeper();

        koala.addKoalaListener(zooKeeper);
        koala.setHungry(true);
        assertEquals("The zookeeper should get notification",
                "Oh, the koala is hungry. It needs some eucalyptus.",
                logMsgCaptor.getMsg());
    }
LogMsgCaptor is a Mockito-based helper class that I wrote to collect logged messages so that I can test what was logged. Assert.assertEquals comes from JUnit and it makes our test case fail if the message logged does not match to what we expected.


What is the difference between Java Observable/Observer and EventListenerList?

Functionally, they have only minor differences.

The EventListenerList is designed to hold several different types of listener in it. If you would be implementing an user interface class, you could stuff all your MouseListeners, KeyListeners, ActionListeners and what have you, to this same EventListenerList. When the notification time comes, you can easily define which listeners should receive which event. While Observable happily stores any type of Observers, it always notifies all of them using the same argument.

But Observable has an inbuilt change-detection system, and that is something EvenListenerList does not have. The Observable sends notifications only if it has changed, and after the notifications have been sent, it does not send more notifications unless it is marked changed again.

Stylewise, EventListenerList is more elegant of the two. You should always favor composition over inheritance.

When you use composition, like we did here, you can hide the parts of the functionality that are not needed at the moment. If we wanted, we could easily remove the removeKoalaListener method from our Koala. But when you extend the Observable, you cannot hide or remove anything.

You can also restrict the visibility of the methods that should not be accessed from outside the class. Take a look at the fireKoalaChanged method of our Koala. It is private, so no-one can force the Koala to send notifications from outside. The respective methods in the Observable are all public or protected.

Also, as the EventListenerList does not come with predefined notification interface, you probably end up defining interfaces that suit your purposes better.

If you really need to implement a full-fledged Observer Pattern, EventListenerList is an good way to do that.

In the next part we are going to revisit the Java Observer/Observable using Generics.

October 30, 2011

Observer: Part II - Degenerated Observer


This is continuation from Observer: Part I - How to mess up your code with it.

In the previous part, I demonstrated some problems caused by a poor implementation of the Observer Pattern. In this and the next parts I am going to use the same Koala Zoo example to demonstrate how to implement it better.

Today we will be lazy and try to avoid implementing the pattern altogether.


Do it better - Degenerate the pattern

Often what we see is not a need for the full-fledged Observer Pattern, but a possible future need for it. In those cases, just save yourself some time and trouble and do not implement the pattern yet. Prepare for the need, but leave the implementation for the future.

Let's see how the Koala would be implemented using that mindset:
    public class Koala {
        private KoalaObserver keeper;

        public void setHungry(final boolean isHungry) {
            if (keeper != null) {
                keeper.koalaUpdate(this, isHungry);
            }
        }

        public void setObserver(final KoalaObserver keeper) {
            this.keeper = keeper;
        }

        @Override
        public String toString() {
            return "koala";
        }
    }

Instead of inheriting from the java.util.Observable, we now implement a very degenerated version of Observable ourselves.

As we need only one Observer we implement method setObserver, instead of addObserver. We do not provide method for deleting the Observer, unless we really need that. There is no change detection either. Just implement the bare minimum.

But we do need the interface for the KoalaObserver:
    public interface KoalaObserver {
        void koalaUpdate(Koala koala, boolean isHungry);
    }

Note that we are now able to pass on the information with correct types. Instead of two Objects, we are passing the Koala and a boolean telling whether the Koala is hungry. If you would need to pass more information, a good rule of thumb is to have maximum of four parameters in a method. So you might add two more parameters, like isAngry and isSick, but after that you should really refactor your code and implement a KoalaChangeEvent that would contain the parameters that need to be passed.

Now we are ready to implement the actual Observer:
    public class ZooKeeper implements KoalaObserver, WaterPipeObserver {

        @Override
        public void koalaUpdate(final Koala koala, final boolean isHungry) {
            if (isHungry) {
                LOGGER.info("Oh, the "
                        + koala
                        + " is hungry. I'll go into the cage and give" 
                        + " some eucalyptus to the little fella!");
            }
        }

        @Override
        public void pipeFixingNeeded() {
            LOGGER.info("Gonna fix the pipe now!");
        }
    }
Now the class declaration nicely tells us what entities the ZooKeeper is observing. I added the WaterPipe from the previous posting to demonstrate how all the different updates no longer go to a common update method. We are free to invent method names that really describe what is happening.

Last, here is how you would use the classes:
    public void testKoalaGetsFood() {
        final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
        final Koala koala = new Koala();
        final ZooKeeper zooKeeper = new ZooKeeper();

        koala.setObserver(zooKeeper);
        koala.setHungry(true);
        assertEquals(
                "The koala should get food",
                "Oh, the koala is hungry. I'll go into the cage and give" 
              + "some eucalyptus to the little fella!",
                logMsgCaptor.getMsg());
    }

If you now tried to do similar mistakes that we did in part I you would get compilation errors.
As you can see, methods are more descriptive and it is easier to see what each of the classes do just by looking at the classes themselves.

Overall, this degenerated pattern offers several advantages compared to using java.util.Observable and java.util.Observer. We have less functionality to maintain. Code is easier to read and debug. We get compilation errors if we break the pattern.


Pitfalls

There are two pitfalls here.

1. Skipping the interface

If you are a beginner, you might be tempted to skip the interface and just implement setKeeper(ZooKeeper keeper) method in the Koala. Do not do that - do not trust the Koala

The Koala or any Observable is not supposed to have full access to its Observer. Eventually someone is going to add some methods to the ZooKeeper that are too tempting for the Koala, like tieYourShoeLacesTogether. No Koala would miss that one. Even if you can keep yourself from calling those methods, the future maintenance person will not hesitate. If he can do something, he will.

2. Forgetting to synchronize when refactoring the code

Sometimes you do need to refactor the code later and add a list of Observers. You might be tempted to just add a List to hold the Observers and be done with it. Do not do that! The full-fledged Observer Pattern implementation needs synchronization.


Can you really do that? You'll have to implement the Observer Pattern sooner or later!

Well, it depends on the case. I have been using this deprecated pattern for over 5 years. I can still count with my one hand fingers the times that I needed to refactor the code to use a real Observer Pattern. Usually people have great plans for the future, but they never get implemented. You should prepare for the future, but never implement things that are not really needed now.

In most cases the Observable does just fine with one Observer. Sometimes there are cases where more Observers are needed, but this degenerated pattern is easily updated by storing the observers in a list and adding addObserver method. That will work as long as the Observers are added during initialization and synchronization is not needed. And with the Collections.synchronizedList(List list) you will add the synchronization in a minute, if needed.

Sometimes you will have a case where the Observers are added and removed on the fly from different threads and you need to make conditional notifications and/or store different types of Observers. Those cases are rare, but sometimes do happen. For those ones, you need a more complete implementations of the pattern. Let's take a look at those in the next parts.

October 29, 2011

Who is my Koala keeper?



This post contains answers to the puzzler presented in my previous post Observer Pattern: Part I - How to mess up your code with it.


All the code presented in the previous post is here:



What was wrong with the code?

There were 3 things wrong with the code:
  1. The WaterPipe is not getting fixed
  2. The Boss is observing the Koalas, but when they are hungry, all he does is complain
  3. Whenever the ZooKeeper feeds a Koala, the Boss is notified twice


Was the Boss supposed to observe the Koala?

Well, we have no way of knowing for sure just by looking at the code. I try to avoid puzzles with no clear answer in the future, but there was no going around for this one. When you do not type strictly, you just miss the information in the code if something goes wrong.

The initial though you probably had is that it probably is a mistake to add the Boss as the observer for the Koala, because he does not have the Koala-feeding code in his update method. But you cannot know for sure.

It is also possible (though not probable) that, for example, the Boss was supposed to feed the Koalas while the ZooKeeper is on vacation, but the implementation was never completed. We would need to search through the code and try to find if ZooKeeper ceases to observe the Koalas at some point. If we find such a code, we must fix the Boss so that he can feed the Koalas. If the ZooKeeper is available all the time, we can assume that the Boss should probably not be observing the Koalas. 



Could something like this really happen? Why would someone code something like this?

Yes, and no. 

The broken pipe was my own addition. As we do not have a complex subject and 10.000-50.000 lines of code here, I needed some distraction for you. I do not think it is a common mistake to totally mix up the observers like that. That type of mistake is possible, but as the pipe-fixing functionality would stop working altogether, it would be caught in the testing quite fast and thus the error would not survive long. 

But what happened with the Boss is real. I have fixed a similar bug. One of the nasty things about this pattern implementation is that the only reference to update method is in the java.util.Observable. The codebase had about 10 different Observers and I had to check through them all while I tried to find out who should observe who. Only after that was clear, was I able to concentrate on trying to find out what is wrong. The update method having and argument of Object array with four unknown Boolean and Integer parameters did not help either. 

Finally I came into conclusion that probably the Boss and the ZooKeeper had originally both been observing the Koala. At some point someone had thought that it is better that the ZooKeeper keeps the Boss informed. And while he remembered to remove the Koala-feeding code from the Boss, he did not remember that the Boss was still added as Observer for Koalas. We were getting quite a lot of extra notifications! 

While the similar situation could have occurred with better implementation of the Observer Pattern, it could not have happened by mistake. If strict types would have been used, the programmer would have gotten a compilation failure for trying to add the Boss as an observer for Koala.

In the next part of this series, I'll show you better ways to implement the Observer Pattern.





October 22, 2011

Observer: Part I - How to mess up your code with it


The Observer pattern is one of the patterns published in the Design Patterns book by the Gang of Four. It is needed when you have an object that changes it's state and you want other objects to notice the change.

If you are programming Java user interfaces you cannot really avoid this pattern. The whole Java event handling is based on it. So whenever you are writing event listeners for Swing components, you are actually using this pattern.

But Java also offers an implementation of the Observer interface and an Observable class to go with the interface. The problem with the Java Observer and Observable is that they were written before the Generics and so they use plain Objects to pass information. While that is not a problem in small hobby projects, it may lead to disasters in larger applications.


If you want to create easily maintainable code, you need to enforce the strong type checking that Java offers.

I guess most of you have heard that before. But maybe some of you have not seen what may happen when that rule is broken. And that is what I am about to demonstrate today. This is a beginner-level article. If you have already messed up your code by violating the rule and always try to avoid casting objects in your code, you might want to just quickly browse through the code and read the puzzler at the end of the post.


How to mess up your code with Java Observer

I am going to demonstrate the problem with a simple example from the Koala Zoo. In the very first version of the Koala Zoo we have just a Koala and a ZooKeeper, who gives food to the Koala when it is hungry.

Let's start by implementing the Koala using the Java Observable:
    public class Koala extends Observable {

        public void setHungry(final boolean isHungry) {
            setChanged();
            notifyObservers(isHungry);
        }

        @Override
        public String toString() {
            return "koala";
        }
    }

There we go! In real life the Koala class would probably be a bit more complex, but this is enough for our purposes. As you notice, Observable is a class and needs to be extended by our Koala.

Let's continue and create our Observer, the ZooKeeperObserver is an interface with a single method for getting updates from the Observable:
    public class ZooKeeper implements Observer {

        @Override
        public void update(final Observable animal, final Object arg) {
            if (arg instanceof Boolean) {
                final boolean isHungry = (Boolean) arg;
                if (isHungry) {
                    LOGGER.info("Oh, the " + animal
                            + " is hungry. I'll go into the cage and "
                            + "give some eucalyptus to the little fella!");
                }

            }
        }
    }

Our Observable and Observer are ready to go, let's test how they work:
    public void testKoalaGetsFood() {
        final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
        final Koala koala = new Koala();
        final ZooKeeper zooKeeper = new ZooKeeper();

        koala.addObserver(zooKeeper);
        koala.setHungry(true);
        assertEquals("The zookeeper should get notified",
                "Oh, the koala is hungry. I'll go into the cage and "
                        + "give some eucalyptus to the little fella!",
                logMsgCaptor.getMessage());
    }

LogMsgCaptor is a Mockito-based helper class that I wrote to collect logged messages so that I can test what was logged. Assert.assertEquals comes from JUnit and it makes our test case fail if the message logged does not match to what we expected.

As we can see, the code works nicely and ZooKeeper is able to keep the Koala stuffed with eucalyptus. But things are going to change when the code evolves.

The Zoo is growing and getting new animals. Introduce the Tiger!
    public class Tiger extends Observable {

        public void setHungry(final boolean isHungry) {
            setChanged();
            notifyObservers(isHungry);
        }

        @Override
        public String toString() {
            return "tiger";
        }
    }

At this point I might spare a thought on whether I could use a common superclass called Animal. But as it's easy to refactor later and pull the methods up, I am not going to do that now.

The Tiger observable is ready to use, but we have not made any changes to our Observer, the ZooKeeperThe nasty thing is that we can actually add the ZooKeeper as an observer for Tiger already and we get no compilation errors when we compile the code. Huh? The ZooKeeper is an observer for Koala, and as the update method is passing Objects as arguments, compiler have no way to know that the method is not implemented properly.

That means we need to REMEMBER to update the ZooKeeper's update method, so that he knows how the Tiger needs to be feed. But hey, that's no problem at all. I have great memory! If I sometimes forget my keys or the dinner or my pants or something it is just because I am thinking something else. But enough blabbering, let's have a coffee break. I suggest you to have a cup too!

Are you back yet? Where were we? Yeah, the Tiger. Let's continue and implement our new test case, the one where the ZooKeeper is feeding the Tiger:
    public void testTiggerGetsFood() {
        final LogMsgCaptor logMsgCaptor = new LogMsgCaptor(LOGGER);
        final Tiger tigger = new Tiger();
        final ZooKeeper zooKeeper = new ZooKeeper();

        tigger.addObserver(zooKeeper);
        tigger.setHungry(true);
        // As this test goes through OK, we forgot to update the ZooKeeper 
        assertEquals("Hmmm. Should the zookeeper go into the cage?",
                "Oh, the tiger is hungry. I'll go into the cage and "
                        + "give some eucalyptus to the little fella!",
                logMsgCaptor.getMessage());
    };
Oh well, what do you know... I'll fix the code in a minute...

I know that at this point some of you are thinking that this is not a big deal. But as time goes by and code gets filled up with little slips like the one I made above, results can be... interesting.

Let me show you an example with a little puzzler.


Puzzler: Koala Zoo after 2 years

The application has expanded and the Zoo now has new personnel. The ZooKeeper has been changed, and he has a Boss to report to:
    public class Boss implements Observer {

        @Override
        public void update(final Observable observable, final Object arg) {
            if (observable instanceof ZooKeeper) {
                ((ZooKeeper) observable).getStatusReport();
            }

            LOGGER.info("I hate being bugged with little things");
        }

    }

We can see that the ZooKeeper has become Observable too. Here is the new code for the ZooKeeper:
    public class ZooKeeper extends Observable implements Observer {

        public void getStatusReport() {
            LOGGER.info("Well, I have taken care of everything");
        }

        @Override
        public void update(final Observable observable, final Object arg) {
            final boolean argIsTrue = Boolean.TRUE.equals(arg);
            if (observable instanceof Koala && argIsTrue) {
                LOGGER.info("The lazy critter is hungry again, I cannot believe how much it eats");
            }
            else if (observable instanceof WaterPipe && argIsTrue) {
                LOGGER.info("I'll do what needs to be done");
            }

            if (argIsTrue) {
                setChanged();
                notifyObservers();
            }
        }
    }

Oh, it seems that the ZooKeeper now observers a WaterPipe too. But what is the argument? Lets check that out the WaterPipe to find out:
    public class WaterPipe extends Observable {

        public void setBroken(final boolean isBroken) {
            setChanged();
            notifyObservers(isBroken);
        }

        @Override
        public String toString() {
            return "watering system";
        }
    }

Oh, the argument is telling if the pipe is broken!
Let's see how all these classes are used:
        final List fifteenKoalas = initKoalas();
        final WaterPipe pipe = new WaterPipe();
        final ZooKeeper zooKeeper = new ZooKeeper();
        final Boss boss = new Boss();
        zooKeeper.addObserver(boss);
        pipe.addObserver(boss);

        for (final Koala koala : fifteenKoalas) {
            koala.addObserver(boss);
            koala.addObserver(zooKeeper);
        }

And as you might guess, this code is not working.

What is wrong and how would you fix it? Is the Boss supposed to observe the Koalas?

I'll tell you the answers in the next post.