Factory Design Pattern made simple using Enums

· JavaDesign Patterns

Writing X2J I encountered a state most of us encountered before: The need for a Factory Design Pattern. In my situation, during parsing (using SAX), there is an interface called ContentHandler (javadoc) which is required by my handler. The handler should be created according to the type of the element being currently parsed. An obvious case for a Factory.

Now, I already have an enum such as:


public enum ObjectType {
    ELEMENT,
    ARRAY;
}


I can have a factory class like this:


public class HandlerFactory() {
    /* .. singleton stuff .. */

    public ContentHandler createHandler(ObjectType type) throws X2JException {
        ContentHandler handler = handlers.get(type);

        if (handler == null) {
          switch (type) {
            case ELEMENT:
              handler = new ElementHandler();
              break;
            case ARRAY:
              handler = new ArrayHandler();
              break;
          }
          handlers.put(type, handler);
        }

        return handler;
    }
}


However, since enums can now have properties and methods as part of Tiger's new features and they're not just a group of constant integers, I can do the following:


public enum ObjectType {
    ELEMENT(ElementHandler.class),
    ARRAY(ArrayHandler.class);

    public Class<? extends ContentHandler> handlerType;

    ObjectType(Class<? extends ContentHandler> handlerType) {
        this.handlerType = handlerType;
    }
}


And the factory becomes very simple, such as:


public ContentHandler createHandler(ObjectType type) throws X2JException {
        ContentHandler handler = handlers.get(type);

        if (handler == null) {
            try {
                handler = type.handlerType.newInstance();
            } catch (Exception e) {
                throw new X2JException(String.format(\"Fail to create handler %s\", type), e);
            }

            handlers.put(type, handler);
        }

        return handler;
    }


The added bonus is that I don't have to worry about this factory class anymore - Whatever new enum values I add, the factory will not be changed. I wish I could somehow get away from calling newInstance(), but I guess it's neglegible because I do that once per enum value, which isn't a lot.

Simple, eh?

Comments (6)

Anonymous
Why not pass an actual factory instance to the enum instances instead of only the class?
Avah
Fine question.

Obviously, it Can be done - I just wanted to avoid writing many classes. Obviously, one could write a generified class HandlerFactory (typed T) which performs "return new T()".

Specifically for my case it was more difficult to do - I had different parameters and caches of handlers that I wanted more control over than in the static methods of Enum, but indeed if I didn't, your solution would have been the better-looking one!

Thank you annonymous! :)
Anonymous
You're welcome :)
Tricks with Enums at Chaotic Java
[...] Simple, isn’t it? The compiler does all of this for you. It’s just a regular class and instances, in every way. And as such, you can add methods to it, add fields to it, and then - Use them at your code for good measure. You can see how I used enums in my code as factory methods, and it’s not the only example at all. Almost any time you’d want to use a switch statement to perform something with a known set of parameters or determine a specific value, you could replace it with an enum method or field. [...]
Avah
It is! I use it whenever reasonable, and it proves itself in creating very maintainable code each time, both in creating all the classes and in removing the need for the huge "switch" case or behavior map.