Konrad Reiche About Photos Talks

Enum Factory Pattern

For my last student research project I wanted to model classes with a set of fixed values. Enum types are a great alternative when working with constant values, especially when they are supposed to encapsulate more than just the value itself. By declaring additional fields or methods the enum type can be enriched with a lot of information. What I did not know so far, is the fact, that it is also possible to declare annotations per enum constant. For example like this:

public enum License {

        @Resource("http://www.apache.org/licenses/LICENSE-2.0")
        APACHE("Apache License, Version 2.0")

        @Resource("http://www.creativecommons.org/licenses/by/3.0")
        CC_BY("Creative Commons Attribution")

        @Resource("http://www.creativecommons.org/licenses/by-sa/3.0")
        CC_BY_SA("Creative Commons Share Alike")

        @Resource("http://www.creativecommons.org/licenses/by-sa/3.0")
        CC_SA("Creative Commons Non-Commercial")

        @Resource("http://www.creativecommons.org/publicdomain/zero/1.0")
        CC_ZERO("Public Domain – No Rights Reserved"),

        @Resource("http://www.gnu.org/licenses/gpl.html")
        GNU_GPL("GNU General Public License")

        String name;

        License(String name) {
                this.name = name;
        }
}

This way metadata can be added without cluttering the enum type constructor. I was faced with the problem to assign fields with the appropriate enum constant based on a database entry. These differed in many ways from the actual enum constant. Hence, I was forced to write a method which parses the database entry and modifies the string before passing it to Enum.valueOf(String).

Fields of these enum types had to be assigned with the concrete enum constant dynamically. With reflection this can be achieved in a generic fashion. In order to implement this Enum Factory I defined a marker interface:

public interface EnumEntity {

}

The marker interface is used to ensure type safety. Another interface EnumFactory is responsible for returning the right enum constant based on the input:

public interface EnumFactory<T extends EnumEntity> {

        public T create(String value);
}

Normally, this would require two Java files which can lead to a lot of files if you define many enum types. By defining the factory in the enum class file itself as a static class making it a de facto top-level class this problem is avoided.

public class LicenseFactory implements EnumFactory<License> {

        @Override
        public License create(String value) {
                // ...
                return valueOf(value);
        }
}

But how does the code responsible for assigning the enum constants knows which class holds the appropriate factory method? By annotating each enum class with @Factory the concrete class can be identified later with reflection:

@Factory(License.LicenseFactory.class)
public enum License implements EnumEntity {
        // ...
}

I found this pattern very handy. By taking advantage of the annotation and reflection functionality of Java it allowed me to automate the enum creation in a generic way without using too much specific code.