Monday, January 28, 2013

"Observer" Design Pattern in Java

Introduction

The Java Platform used to have support for Observer design pattern in the form of Observer interface and Observable class starting from its initial release. However a long time passed since then. A lot of enhancements were added to the standard libraries and to the Java language itself. In this post I want to describe how generics and Java Collections Framework can be used together to build a better Observer design pattern implementation.

What’s wrong with Observer and Observable?

Before building a better implementation we need to identify the flaws of what we currently have. The JDK support for Observer design pattern has the following problems:
  1. It doesn’t use generics which are a must in the modern Java programming.
  2. Internally (at least when it comes to Oracle JDK 6 and JDK 7) Observable implementation uses synchronization inefficiently: it leverages Vector class which is synchronized by itself in addition to custom synchronization logic.
Let’s see how we can tackle the aforementioned issues using modern JDK facilities.

Observer Revised

The following subsections show how generics and Java Collections Framework can be leveraged to build modern Observer design pattern implementation.

Initial Implementation

First of all, we need to introduce generic analogues to standard JDK Observer interface and Observable class. Let them be EventListener and EventPublisher respectively:
// EventListener.java
public interface EventListener<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> {

    void handleEvent(P sender, E event);

}

// EventPublisher.java
public interface EventPublisher<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> {

    void addListener(L listener);

    void removeListener(L listener);

    void clearListeners();

    void publishEvent(E event);

}
Programming to interfaces instead of concrete classes is considered a good practice, that’s why Observable class has been replaced with a generic interface, not a generic class. The definitions of these interfaces may seem a bit weird at first glance. Let’s break them down to see what’s happening.

Let’s begin with the EventListener interface. We need to parameterize the type of event publisher to accept events from and the type of events to listen to. So we can start with the following definition:
// EventListener.java
public interface EventListener<P, E> {
    // ...
}
For EventPublisher interface we need to parameterize the type of event listener to notify and the type of events to publish. The following definition can be used to express this:
// EventPublisher.java
public interface EventPublisher<L, E> {
    // ...
}
It is known that every event publisher should implement EventPublisher interface and every event listener should implement EventListener interface. Let’s express this idea in code with type variable bounds:
// EventListener.java
public interface EventListener<P extends EventPublisher<???, E>, E> {
    // ...
}

// EventPublisher.java
public interface EventPublisher<L extends EventListener<???, E>, E> {
    // ...
}
This is invalid Java code of course. Triple question mark is used to indicate problems. Type variable P of EventListener is bounded by EventPublisher which is generic by itself. Hence we need to provide certain values (type arguments) for event type (E) and event listener (L) type variables of EventPublisher interface. The solution is trivial for event type: type variable E can be reused. But what should be passed as type argument for event listener?

Similar reasoning can be applied to EventPublisher interface. Type variable L of EventPublisher is bounded by EventListener which is generic by itself. Hence we need to provide certain values (type arguments) for event type (E) and event publisher (P) type variables of EventListener interface. The solution is trivial for event type: type variable E can be reused. But what should be passed as type argument for event publisher?

To solve the aforementioned problems and to convert the previous erroneous listing to the working Java code we need to introduce two more type variables:
  1. In EventListener interface definition L type variable will denote event listener type to notify. The only purpose of the L type variable is to serve as the type argument for EventPublisher interface which bounds P type variable of EventListener.
  2. In EventPublisher interface definition P type variable will denote event publisher to accept events from. The only purpose of the P type variable is to serve as the type argument for EventListener interface which bounds L type variable of EventPublisher.
In the end we have two generic interfaces with mutually recursive type variable bounds. The definitions of these interfaces now look similar to the ones at the beginning of this subsection:
// EventListener.java
public interface EventListener<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> {
    // ...
}

// EventPublisher.java
public interface EventPublisher<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> {
    // ...
}
And now let’s create AbstractEventPublisher – abstract base class which any event publisher can extend to avoid implementing EventPublisher interface from scratch:
// AbstractEventPublisher.java
public abstract class AbstractEventPublisher<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> implements EventPublisher<P, L, E> {

    private final List<L> listeners = new ArrayList<L>();

    @Override
    public void addListener(L listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(L listener) {
        listeners.remove(listener);
    }

    @Override
    public void clearListeners() {
        listeners.clear();
    }

    @Override
    @SuppressWarnings("unchecked")
    public void publishEvent(E event) {
        for (L listener : listeners) {
            listener.handleEvent((P) this, event);
        }
    }
}
There is nothing special about this class. The only thing worth noting is that it is not thread safe. This issue is tackled in the following subsection.

Naïve Thread-Safety

Quite often event publisher needs to be thread-safe. This subsection is the first try to implement thread-safety for AbstractEventPublisher class. It looks like this:
// AbstractEventPublisher.java
public abstract class AbstractEventPublisher<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> implements EventPublisher<P, L, E> {

    private final List<L> listeners =
            Collections.synchronizedList(new ArrayList<L>());

    @Override
    public void addListener(L listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(L listener) {
        listeners.remove(listener);
    }

    @Override
    public void clearListeners() {
        listeners.clear();
    }

    @Override
    @SuppressWarnings("unchecked")
    public void publishEvent(E event) {
        synchronized (listeners) {
            for (L listener : listeners) {
                listener.handleEvent((P) this, event);
            }
        }
    }
}
In this implementation field listeners is instantiated using synchronizedList() method. Iteration over listeners is contained inside the synchronized block as required by synchronizedList() contract.

Now AbstractEventPublisher class is thread-safe, but it has one serious flaw: it delivers events inside synchronized block. The code inside synchronized block should be as fast as possible because:
  1. No listener can be add/removed while iteration inside synchronized block is in progress.
  2. No other event can be delivered until handling of the currently delivered event is finished.
Depending on the activity performed inside handleEvent method implementation, calling it from synchronized block may lead to performance bottle-necks, exceptions, data corruptions or dead-locks. Joshua Bloch in his Effective Java book (item 67) names methods like handleEvent alien methods. It’s a very apt term because AbstractEventPublihser class has no idea of what event listeners might do as part of their handleEvent implementations. The next subsection shows how to protect against alien methods.

Using List Snapshot

One pretty obvious solution to alien methods problem is to make a copy (snapshot) of the field listeners inside synchronized block and deliver an event using that copy outside the block:
@Override
@SuppressWarnings("unchecked")
public void publishEvent(E event) {
    final List<L> snapshot = new ArrayList<L>();

    synchronized (listeners) {
        snapshot.addAll(listeners);
    }

    for (L listener : snapshot) {
        listener.handleEvent((P) this, event);
    }
}
This approach works fine and allows for avoiding alien methods, but a better alternative exists.

Using Concurrent List Implementation

Starting from Java 5 concurrent collections were introduced to the Java platform as part of the java.util.concurrent package. This package contains a lot of useful stuff to facilitate concurrent programs development. Class CopyOnWriteArrayList is the greatest interest for us. According to documentation it is a thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array. This is ordinarily too costly, but may be more efficient than alternatives when traversal operations vastly outnumber mutations, and is useful when you cannot or don't want to synchronize traversals, yet need to preclude interference among concurrent threads. Hence CopyOnWriteArrayList class perfectly suits our needs:
// AbstractEventPublisher.java
public abstract class AbstractEventPublisher<
        P extends EventPublisher<P, L, E>,
        L extends EventListener<P, L, E>,
        E> implements EventPublisher<P, L, E> {

    private final List<L> listeners = new CopyOnWriteArrayList<L>();

    @Override
    public void addListener(L listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(L listener) {
        listeners.remove(listener);
    }

    @Override
    public void clearListeners() {
        listeners.clear();
    }

    @Override
    @SuppressWarnings("unchecked")
    public void publishEvent(E event) {
        for (L listener : listeners) {
            listener.handleEvent((P) this, event);
        }
    }
}
As you can see this code is almost identical to the very first implementation of abstract event publisher. The only difference is that CopyOnWriteArrayList is used instead of ArrayList to instantiate field listeners.

Practical Usage

Now let’s look at a practical example which incorporates all previously developed stuff. Assume we have class Circle which represents a circle and maintains its center, radius and color via instance fields. Suppose that Circle class instance should publish an event whenever any part of the instance state is changed. Let’s see how we can fulfill the aforementioned requirements based on the previously developed code.

First of all let’s look at the Circle class:
// Circle.java
public class Circle {
    private Point center;
    private int radius;
    private Color color;

    public Circle(Point center, int radius, Color color) {
        this.center = center;
        this.radius = radius;
        this.color = color;
    }

    public Point getCenter() {
        return center;
    }

    public void setCenter(Point center) {
        this.center = center;
    }

    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}
There is nothing special about this class for now. It contains instance fields, getters and setters to retrieve and update instance fields, and a constructor to set initial object state.

Now let’s introduce two interfaces: CircleEvent and CircleEventListener. The first one is a tag interface which every event type published by the Circle class should implement. The second one as you might guess is supposed to be implemented by every circle event listener:
// CircleEvent.java
public interface CircleEvent {
}

// CircleEventListener.java
public interface CircleEventListener extends
        EventListener<Circle, CircleEventListener, CircleEvent> {
}
Remember that EventListener and EventPublisher interfaces have mutually recursive bounds. So in order to compile successfully and build on top of the AbstractEventPublisher class functionality Circle class definition should be modified like this:
// Circle.java
public class Circle extends AbstractEventPublisher<Circle,
        CircleEventListener, CircleEvent> {
// …
}
Now let’s look at the classes representing events itself. The Circle class should fire an event whenever its center, radius or color is changed. Hence there should be three different event types:
// CenterChangedEvent.java
public class CenterChangedEvent implements CircleEvent {
    private final Point oldCenter;
    private final Point newCenter;

    public CenterChangedEvent(Point oldCenter, Point newCenter) {
        this.oldCenter = oldCenter;
        this.newCenter = newCenter;
    }

    public Point getOldCenter() {
        return oldCenter;
    }

    public Point getNewCenter() {
        return newCenter;
    }
}

// ColorChangedEvent.java
public class ColorChangedEvent implements CircleEvent {
    private final Color oldColor;
    private final Color newColor;

    public ColorChangedEvent(Color oldColor, Color newColor) {
        this.oldColor = oldColor;
        this.newColor = newColor;
    }

    public Color getOldColor() {
        return oldColor;
    }

    public Color getNewColor() {
        return newColor;
    }
}

// RadiusChangedEvent.java
public class RadiusChangedEvent implements CircleEvent {
    private final int oldRadius;
    private final int newRadius;

    public RadiusChangedEvent(int oldRadius, int newRadius) {
        this.oldRadius = oldRadius;
        this.newRadius = newRadius;
    }

    public int getOldRadius() {
        return oldRadius;
    }

    public int getNewRadius() {
        return newRadius;
    }
}
All three event classes are designed to be immutable. Each one contains old and new value of the corresponding Circle class instance field. Now let’s include event publishing code in the Circle class setters.
// Circle.java
public class Circle extends AbstractEventPublisher<Circle,
        CircleEventListener, CircleEvent> {

    // …

    public void setCenter(Point center) {
        if (!this.center.equals(center)) {
            publishEvent(new CenterChangedEvent(this.center, center));
        }

        this.center = center;
    }

    public void setRadius(int radius) {
        if (this.radius != radius) {
            publishEvent(new RadiusChangedEvent(this.radius, radius));
        }

        this.radius = radius;
    }

    public void setColor(Color color) {
        if (!this.color.equals(color)) {
            publishEvent(new ColorChangedEvent(this.color, color));
        }

        this.color = color;
    }
}
As you can see Circle class setters publish events using inherited publishEvent method. We’re almost done. To make sure everything works as expected let’s develop a simple circle event handler which will just print relevant message to the console:
// SimpleCircleEventHandler.java
public class SimpleCircleEventHandler implements CircleEventListener {

    private Map<Class<? extends CircleEvent>,
            CircleEventListener> handlers;

    public SimpleCircleEventHandler() {
        handlers = new HashMap<Class<? extends CircleEvent>,
                CircleEventListener>();
        
        handlers.put(CenterChangedEvent.class,
                new CenterChangedEventHandler());
        handlers.put(ColorChangedEvent.class,
                new ColorChangedEventHandler());
        handlers.put(RadiusChangedEvent.class,
                new RadiusChangedEventHandler());
    }

    @Override
    public void handleEvent(Circle sender, CircleEvent event) {
        CircleEventListener handler = handlers.get(event.getClass());

        if (handler != null) {
            handler.handleEvent(sender, event);
        }
    }

    private static class CenterChangedEventHandler implements
            CircleEventListener {
        
        @Override
        public void handleEvent(Circle sender, CircleEvent e) {
            CenterChangedEvent event = (CenterChangedEvent) e;
            String message = "center changed from %s to %s"
            System.out.println(String.format(message,
                    event.getOldCenter().toString(),
                    event.getNewCenter().toString()));
        }
    }

    private static class ColorChangedEventHandler implements
            CircleEventListener {
        
        @Override
        public void handleEvent(Circle sender, CircleEvent e) {
            ColorChangedEvent event = (ColorChangedEvent) e;
            String message = "color changed from %s to %s"
            System.out.println(String.format(message,
                    event.getOldColor().toString(),
                    event.getNewColor().toString()));
        }
    }

    private static class RadiusChangedEventHandler implements
            CircleEventListener {
        
        @Override
        public void handleEvent(Circle sender, CircleEvent e) {
            RadiusChangedEvent event = (RadiusChangedEvent) e;
            String message = "radius changed from %d to %d"
            System.out.println(String.format(message,
                    event.getOldRadius(), event.getNewRadius()));
        }
    }
}
And finally there is a small main program to wire up everything together:
// ObserverMain.java
public class ObserverMain {
    public static void main(String[] args) {
        Circle circle = new Circle(new Point(10, 10), 15, Color.RED);
        circle.addListener(new SimpleCircleEventHandler());

        circle.setCenter(new Point(5, 5));
        circle.setRadius(20);
        circle.setColor(Color.GREEN);
    }
}
This program will print the following output:

center changed from java.awt.Point[x=10,y=10] to java.awt.Point[x=5,y=5]
radius changed from 15 to 20
color changed from java.awt.Color[r=255,g=0,b=0] to java.awt.Color[r=0,g=255,b=0]

Conclusion

Ok, that’s it. As you can see, modern Java allows for building better and more type safe Observer design pattern implementations compared to standard JDK facilities. Of course it didn’t become as smooth as it should be (compared to events in C# for example), but one day it will certainly do :)

Thanks for reading,
See you soon!

Friday, January 11, 2013

"Singleton" Design Pattern in Java

Introduction

Singleton design pattern is a very disputable issue. There are tons of discussions in the Internet about Singleton usage in application design, why to use it, why not to use it, why singletons are evil, etc. In this post I want to put aside the “why?” part of the issue and concentrate on the “how?” part. In particular how to implement Singleton design pattern in Java. The rest of the post enumerates all Singleton implementation options I’ve ever encountered and describes their pros and cons. It doesn’t pretend for completeness but rather reflects my personal experience of working with this design pattern.

General Information

Singleton design pattern is intended to restrict the instantiation of a class to one (single) object. It should do the following things:

  • Ensure that only one instance of a class is created.
  • Provide a global point of access to that instance.

Let’s see how aforementioned points can be implemented in Java.

Singleton in Java

The following subsections describe different approaches to Singleton design pattern implementation in Java. If you are currently not interested in Singleton evolution in Java, want to skip all the background information and just need to find the best working solution quickly then jump straight to the last subsection which describes Singleton implementation using single-element enumeration.

First Option

The most obvious Singleton implementation looks like this:
public class Singleton1 {
    private static Singleton1 instance;

    private Singleton1() {
    }

    public static Singleton1 getInstance() {
        if (instance == null) {
            instance = new Singleton1();
        }

        return instance;
    }
}
This solution has one serious drawback: it doesn’t take threading into account and hence may not work as expected in multithreaded environment. If two or more threads call getInstance() method simultaneously then race condition occurs. For example, if 5 threads call getInstance() at the same time you may end up with static instance field being assigned up to 5 times (depending on the thread scheduling mechanism behavior).

Second Option

To tackle threading issue the previous option is suffering from you can try to use the following solution:
public class Singleton2 {
    private static final Singleton2 instance = new Singleton2();

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        return instance;
    }
}
In this implementation static instance field will be created during class initialization procedure. Java Language Specification guarantees this procedure to be thread-safe. Therefore this option is suitable for multithreaded environments, but it isn’t perfect either. It has the following drawbacks:

  • It cannot handle exceptions which may occur in the constructor.
  • Static instance field is no longer initialized lazily.

These points are not as critical as threading issue and they can be an acceptable trade-off depending on the task at hand. Moreover, you can easily overcome the first drawback by using a static initializer:
public class Singleton2 {
    private static final Singleton2 instance;

    static {
        try {
            instance = new Singleton2();
        } catch (Exception e) {
            // do possible error processing
            throw new RuntimeException(e);
        }
    }

    private Singleton2() throws Exception {
        // complex initialization logic which can throw an exception
    }

    public static Singleton2 getInstance() {
        return instance;
    }
}
This code looks a bit awkward, but it works and can be used if exceptions thrown from a constructor are a concern. But what if we want to preserve lazy initialization? This naturally leads us to the third option.

Third Option

The following Singleton implementation was initially suggested by Bill Pugh. It is called “Initialization on Demand Holder”. The trick is to use private nested class to hold Singleton instance:
public class Singleton3 {
    private Singleton3() {
    }

    private static class SingletonHolder {
        public static final Singleton3 instance = new Singleton3();
    }

    public static Singleton3 getInstance() {
        return SingletonHolder.instance;
    }
}
This solution leverages lazy initialization. Static instance field is initialized no earlier than SingletonHolder class is loaded and initialized. SingletonHolder class in its turn is loaded and initialized no earlier than it is first referenced. Finally SingletonHolder class is first referenced no earlier than getInstance() method is called. And this is exactly what we need. This implementation like the previous one is also based on the class initialization procedure which is guaranteed by Java Language Specification to be thread-safe. Similarly to the second option, if exceptions thrown from a constructor are a concern you can use a static initializer:
public class Singleton3 {
    private Singleton3() throws Exception {
        // complex initialization logic which can throw an exception
    }

    private static class SingletonHolder {
        public static final Singleton3 instance;

        static {
            try {
                instance = new Singleton3();
            } catch (Exception e) {
                // do possible error processing
                throw new RuntimeException(e);
            }
        }
    }

    public static Singleton3 getInstance() {
        return SingletonHolder.instance;
    }
}
So now we have a thread-safe Singleton implementation which initializes its instance lazily on demand. If you are using Java 1.4 or earlier then this is the approach to stick with.

Fourth Option

Before Bill Pugh suggested his “Initialization on Demand Holder” technique one of the most popular implementations of lazy-initializing thread-safe Singleton used to look like this:
public class Singleton4 {
    private static Singleton4 instance;

    private Singleton4() {
    }

    public static synchronized Singleton4 getInstance() {
        if (instance == null) {
            instance = new Singleton4();
        }

        return instance;
    }
}
This solution has only one drawback: it uses synchronization inefficiently. Synchronization is necessary only until the static instance field is not initialized. After that it simply wastes CPU cycles. In earlier implementations of the Java Platform synchronized methods and blocks were quite costly. That’s why the fifth option emerged.

Fifth Option

This solution is intended to tackle inefficient synchronization usage of the previous option. It leverages Double-Checked Locking pattern and like the previous one it also used to be very popular:
public class Singleton5 {
    private static Singleton5 instance;

    private Singleton5() {
    }

    public static Singleton5 getInstance() {
        if (instance == null) {
            synchronized (Singleton5.class) {
                if (instance == null) {
                    instance = new Singleton5();
                }
            }
        }

        return instance;
    }
}
There is only one problem with this approach: it doesn’t work! Broken Double-Checked Locking pattern is a complicated topic which goes beyond the scope of this post, but the interested reader can find more information here.

Sixth Option

Bill Pugh’s efforts on Double-Checked Locking led to changes in Java Memory Model which were incorporated in the Java Platform starting from Java 5. With these changes it became possible to make the previous solution work by adding volatile modifier to the instance field declaration:
public class Singleton6 {
    private static volatile Singleton6 instance;

    private Singleton6() {
    }

    public static Singleton6 getInstance() {
        if (instance == null) {
            synchronized (Singleton6.class) {
                if (instance == null) {
                    instance = new Singleton6();
                }
            }
        }

        return instance;
    }
}
This solution will work correctly in Java 5 and above.

Seventh Option

All previously mentioned Singleton implementations suffer from the following drawbacks:

  • It is possible to instantiate more than one Singleton instance using Java reflections. All you need to do is to get the corresponding Constructor instance, make it accessible using method setAccessible() and call the constructor reflectively. You can protect your Singleton class against this invocation by throwing an exception from the constructor if an attempt to create more than one Singleton instance is taken.
  • If Singleton class implements Serializable interface additional precautions should be taken to maintain Singleton guarantee: all fields of the Singleton class should be made transient and readResolve() method should be implemented to replace any deserialized instances coming from ObjectInputStream with the only true one.

While you do can bother with tackling the aforementioned problems manually, there is a much better approach which solves them automatically:
public enum Singleton7 {
    INSTANCE
    // ...
}
As you might know, enumerations in Java are not just a set of constants. They can contain method implementations and hence can be used to implement Singleton’s logic instead of plain class. Moreover, all serialization and multiple instantiation issues are handled automatically. I first encountered the idea of using single-element enumerations to implement Singleton design pattern in Joshua Bloch’s Effective Java book. At the time of this writing it is the best way to implement Singleton in Java.

Thanks for reading,
See you soon!

Monday, January 7, 2013

Variation of "State" Design Pattern in Java

This post is about a variation of “State” design pattern implemented in Java. I used similar approach in one of the projects I’ve been working on and I found it pretty useful. I assume you are familiar with “State” design pattern. I would suggest reading this introduction if this is not the case. Alternatively you can learn about the pattern from the famous GoF book.

Ok, let’s start. Consider the following scenario: you are working on a software system which should integrate at certain points with another system using SOAP web-services. Workflow of your software system highly depends on this integration, but the external system may be occasionally unavailable or require a long time to respond. This can significantly slow down your development activities.

If you know the expected outcome of the external system then you can simulate it locally during development phase without actual invocation. One of possible approaches is to put all the integration logic in a separate component and make the rest of your system talk to the external system via that component exclusively. The integration component in its turn can be configured to either invoke the real external system or to simulate locally its expected outcome. Let’s look at some code.

The integration component interface might look like this:
public interface ExternalSystemClient {

    AppResult invokeExternalSystem(AppParams params);

}
For simplicity it contains just a single method which invokes an external system and delivers its outcome. AppParams and AppResult classes represent invocation parameters and invocation result respectively in terms of application. Integration component’s responsibility is to convert them to the form understandable by external system (WebServiceParams and WebServiceResult introduced in the next listing). Implementation of integration component might look like this:
public class ExternalSystemClientImpl implements ExternalSystemClient {
    private ClientActions clientActions;

    public ExternalSystemClientImpl(boolean isExternalSystemEnabled) {
        clientActions = isExternalSystemEnabled ?
                new ExternalSystemEnabled() : 
                new ExternalSystemDisabled();
    }

    private interface ClientActions {
        WebServiceResult invokeExternalSystem(
                WebServiceParams webParams);
    }

    private class ExternalSystemEnabled implements ClientActions {
        @Override
        public WebServiceResult invokeExternalSystem(
                WebServiceParams webParams) {
            // invoke external system and return the results
        }
    }

    private class ExternalSystemDisabled implements ClientActions {
        @Override
        public WebServiceResult invokeExternalSystem(
                WebServiceParams webParams) {
            // simulate external system outcome
        }
    }
    @Override
    public AppResult invokeExternalSystem(AppParams params) {
        // validate input parameters
        // ...
        WebServiceParams webParams = new WebServiceParams();
        // convert AppParams to WebServiceParams
        // ...
        WebServiceResult invocationResult =
                clientActions.invokeExternalSystem(webParams);

        AppResult result = new AppResult();
        // convert WebServiceResult to AppResult
        // ...
        return result;
    }
}
Let’s break down this listing into individual parts. Class ExternalSystemClientImpl implements ExternalSystemClient interface to provide integration with external system. This class contains one private interface – ClientActions. This interface helps to factor out the code which directly depends on whether external system invocation should be performed or not. Hence there are two implementations of ClientActions interface: ExternalSystemEnabled (which do performs external system invocation) and ExternalSystemDisabled (which is intended solely for development purposes and simulates the invocation locally).

Interface ClientActions plus classes ExternalSystemEnabled and ExternalSystemDisabled effectively form the crux of the “State” design pattern. A certain state is selected in the ExternalSystemClientImpl constructor depending on the value of isExternalSystemEnabled parameter. Method invokeExternalSystem() shows “State” design pattern in action. This method has the following responsibilities:

  • Validate input parameters.
  • Convert AppParams instance to the form understandable by the external system (i.e. convert AppParams instance to WebServiceParams instance).
  • Invoke the external system via web-service.
  • Convert WebServiceResult to the form understandable by our application (i.e. convert WebServiceResult to AppResult) and return it.

As you can see the implementation of this method is completely independent of whether the external system is actually invoked or its outcome is locally generated. The more methods you have in ExternalSystemClient interface, the greater benefit you gain from “State” design pattern application.

Alternative Techniques

Let’s look at some alternatives. The first and the most obvious one is to simply check the flag in the ExternalSystemClientImpl#invokeExternalSystem() method and act accordingly depending on the result. The implementation might look like this:
@Override
public AppResult invokeExternalSystem(AppParams params) {
    // validate input parameters
    // ...
    WebServiceParams webParams = new WebServiceParams();
    // convert AppParams to WebServiceParams
    // ...

    WebServiceResult invocationResult;

    if (isExternalSystemEnabled) {
        invocationResult = // ... invoke actual external system
    } else {
        invocationResult = // ... simulate invocation result locally
    }

    AppResult result = new AppResult();
    // convert WebServiceResult to AppResult
    // ...

    return result;
}
This is not an option to be honest. The more methods you have in ExternalSystemClient interface, the more headaches you get during maintenance due to code duplication. Assume you have 15 methods and you need to introduce the third state. If you stick to the aforementioned approach then you will have to revisit all these methods to add new state handling. Code duplication is always error-prone and should be avoided. “State” design pattern works much better in this case because all you need to do is to introduce another ClientActions interface implementation and slightly modify the ExternalSystemClientImpl constructor.

One viable alternative is to provide ClientActions implementation dependency directly via constructor parameter. In this case the required object can be easily injected using Spring, Guice or any other dependency injection container. Method invokeExternalSystem() will be implemented similarly to the initial “State” design pattern description:
@Override
public AppResult invokeExternalSystem(AppParams params) {
    // validate input parameters
    // ...
    WebServiceParams webParams = new WebServiceParams();
    // convert AppParams to WebServiceParams
    // ...
    WebServiceResult invocationResult =
            clientActions.invokeExternalSystem(webParams);

    AppResult result = new AppResult();
    // convert WebServiceResult to AppResult
    // ...

    return result;
}
The constructor of ExternalSystemClientImpl class will be slightly changed:
public ExternalSystemClientImpl(ClientActions clientActions) {
    this.clientActions = clientActions;
}
This solution works fine and provides the same benefits as the initial one. But in this case ClientActions interface and its implementations cannot be kept private to ExternalSystemClientImpl class anymore. Sometimes this is exactly what we need (for example if ClientActions is a full-fledged component that is injected in several other components in the system), but in this particular case ClientActions, ExternalSystemEnabled and ExternalSystemDisabled are just implementation details, not the components on their own. Hence they should be kept as private as possible.

Thanks for reading,
See you soon!

Wednesday, January 2, 2013

Class Clusters in Java

Introduction

Every good Objective-C programmer knows (or at least should know) what is a class cluster. Indeed this term is frequently mentioned in Apple documentation. It is one of the core patterns of Cocoa and Cocoa Touch. Cocoa Design Patterns book – a must-read for every Objective-C developer – even has a dedicated chapter about class clusters. Is this notion relevant outside Objective-C world? Yes, it is. The following sections describe class clusters in the Java programming language context.

Class Clusters Explained

Basically a class cluster is an abstract class that groups a set of concrete private subclasses together to provide a simplified interface to the user through the abstract class. The main reason for this is to instantiate an appropriate or a more efficient implementation depending on certain user needs. Let’s look at an example to make this more specific. Assume you need to implement Resource class which would allow its users to load and work with different kinds of resources. At first shot you want to add support for http, ftp and file system resources. Using class clusters this example could be implemented as follows:
public abstract class Resource {
    private static final String PREFIX_FILE_RESOURCE = "file://";
    private static final String PREFIX_HTTP_RESOURCE = "http://";
    private static final String PREFIX_FTP_RESOURCE = "ftp://";

    private String url;

    protected Resource(String url) {
        this.url = url;
    }

    protected String getResourceUrl() {
        return url;
    }

    public static Resource getResource(String url) {
        final Resource result;

        if (url.startsWith(PREFIX_FILE_RESOURCE)) {
            result = new FileResource(url);
        } else if (url.startsWith(PREFIX_HTTP_RESOURCE)) {
            result = new HttpResource(url);
        } else if (url.startsWith(PREFIX_FTP_RESOURCE)) {
            result = new FtpResource(url);
        } else {
            throw new IllegalArgumentException(String.format(
                    "unknown protocol for resource: %s", url));
        }

        return result;
    }

    public abstract InputStream getAsStream();

    private static class FileResource extends Resource {
        protected FileResource(String url) {
            super(url);
        }

        @Override
        public InputStream getAsStream() {
            // open and return InputStream for file resource
        }
    }

    private static class HttpResource extends Resource {
        protected HttpResource(String url) {
            super(url);
        }

        @Override
        public InputStream getAsStream() {
            // open and return InputStream for http resource
        }
    }

    private static class FtpResource extends Resource {
        protected FtpResource(String url) {
            super(url);
        }

        @Override
        public InputStream getAsStream() {
            // open and return InputStream for ftp resource
        }
    }
}
Let’s break up this listing. The Resource class contains the following two methods intended for interfacing with client code:

  • getResource() – used to construct a Resource instance from the URL.
  • getAsStream() – used to get resource contents as InputStream.

Each type of resource is implemented as a private static nested Resource subclass. They are FileResource, HttpResource and FtpResource for accessing file, http and ftp resources respectively. For convenience Resource class also has a private instance field url plus protected constructor and getter to facilitate its usage by subclasses. Method getResource() is the most interesting part of the listing. Its code is repeated below for convenience:
public static Resource getResource(String url) {
    final Resource result;

    if (url.startsWith(PREFIX_FILE_RESOURCE)) {
        result = new FileResource(url);
    } else if (url.startsWith(PREFIX_HTTP_RESOURCE)) {
        result = new HttpResource(url);
    } else if (url.startsWith(PREFIX_FTP_RESOURCE)) {
        result = new FtpResource(url);
    } else {
        throw new IllegalArgumentException(String.format(
                "unknown protocol for resource: %s", url));
    }

    return result;
}
There are a few important points to note about this method:

  • The most suitable Resource subclass is selected at runtime depending on certain criteria. Client’s code doesn’t have a compile-time dependency on a certain implementation but rather works in terms of abstract Resource class.
  • Client’s code is unaware of multiple implementations existence. Hence private Resource subclasses can be safely added, merged together or removed without affecting client’s code as long as the new version of abstract Resource class is kept consistent in the behavior with the previous one.

Abstract Resource class and its private nested subclasses (FileResource, HttpResource and FtpResource) effectively form a class cluster. At first glance a class cluster might resemble Abstract Factory design pattern. There are certain similarities indeed, but these patterns have different purposes. Abstract Factory is intended to provide clients with a set of products from the same family (e.g. UI widgets implemented using GTK+, DAO objects implemented using JDBC, etc.). Each concrete factory matching the abstract one instantiates objects from its own product family. Class cluster on the other hand is built around a single abstract class. Its purpose is to group together multiple private subclasses and provide access to them through the interface of the common abstract class. The following program gives a simple example of Resource class usage:
public class ClassClusterExample {
    public static void main(String[] args) {
        final String httpResourceUrl = "http://www.google.com";
        final String fileResourceUrl = "file:///C:/web/resource.txt";
        final String ftpResourceUrl = "ftp://fake.host/resource.txt";

        Resource httpResource = Resource.getResource(httpResourceUrl);
        Resource fileResource = Resource.getResource(fileResourceUrl);
        Resource ftpResource = Resource.getResource(ftpResourceUrl);

        System.out.println(httpResource.getClass().getSimpleName());
        System.out.println(fileResource.getClass().getSimpleName());
        System.out.println(ftpResource.getClass().getSimpleName());
    }
}
This program unsurprisingly will print the following output:

HttpResource
FileResource
FtpResource

Class Clusters in JDK

It turns out that class clusters can be found in JDK itself (at least when it comes to Oracle’s JDK 5 and 6). A typical example is EnumSet<E>. As you might know this class is the most effective way to store sets of enums in Java and it cannot be instantiated directly. You should use static methods to build EnumSet<E> objects. If enumeration used in conjunction with EnumSet<E> contains more than 64 elements then JumboEnumSet<E> will be instantiated. Otherwise RegularEnumSet<E> will be used. Both RegularEnumSet<E> and JumboEnumSet<E> are package-private subclasses of EnumSet<E> and they provide access to their functionality via EnumSet<E> interface. These three classes taken together form a class cluster. Of course everything described in this section is an implementation detail and it might change in the future releases of Oracle’s JDK.

Conclusion

As you can see class cluster is a useful design pattern which goes beyond Objective-C world. It is a convenient way to group together multiple implementations of the same notion and provide access to them through simplified common interface. This approach helps to decouple client’s code from a particular implementation and gives to implementer the flexibility for future modifications.

Thanks for reading,
See you soon!