Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Pleasant Discovery of the Day: Java Enums

This morning I found myself reading through the “Effective Java” book, which I find highly informative. It is far, far better than the typical “syntax only” or “hello world” book because it’s basically a list of recipes on how not to screw up your Java code… an invaluable resource for someone who has been developing Microsoft code nearly exclusively for the past 13 years.

Anyway, I stumbled on a few best practices related to the proper usage of Java enums. To a C# developer this seemed a little odd because, quite frankly, there aren’t all that many things you can do with a C# enum.

In C# when we define an enum, it’s basically to enumerate the possibilities that exist within a finite set. For example, the list of colors available in a WPF/XAML/WP7 GUI or maybe the durability flag for a messaging protocol or the list of possible values for someone’s mood in a social networking app…the list goes on and on, but you get the idea.

The twist that Java seems to put on it is this: what if those enumerated values are rich? What if, in addition to simply exporting a constant that can be used by other code, this constant has additional data, or even simple functionality. This is what Java enums let me do that C# enums don’t (granted, I can use a combination of classes and static fields and methods to accomplish the same thing, but you get the idea).

Let’s say I’m building a zombie game (because, you know, zombies rule). In this game I have a zombie class that needs to keep track of what type of zombie it is. According to the game rules, there is a finite number of possible zombie types. More importantly, for each zombie type, there is a set of metadata such as velocity and strength. Rather than come up with a static array of zombie metadata instances like I might do in C#, I can actually create an enum in Java that not only holds the constant name, but holds the metadata and can even expose simple methods to hide calculations specific to an instance of the enumerated value:

package com.kotancode.zombies;

public enum ZombieType {
    BRAINSUCKER(0.5, 11), SNEAKYBASTARD(5.5, 6), SPEEDFREAK(10.0, 3);

    private final double velocity; // speed of the zombie
    private final double strength; // amount of force zombie can generate

    ZombieType(double vel, double str) {
        velocity = vel;
        strength = str;
    }

    public double velocity() {
        return velocity;
    }

    public double strength() {
        return strength;
    }

    public Boolean isFasterThan(ZombieType zt) {
        return velocity > zt.velocity();
    }
}

What I have here is a rich enum that provides me with a single source of metadata and potentially simple business logic that is associated with the finite set of possible zombie types. To use the zombie type, I can create a Zombie class that looks like this:

package com.kotancode.zombies;

public class Zombie {
    private ZombieType type;
    private String name;

    public Zombie(ZombieType type, String name) {
        this.type = type;
        this.name = name;
    }

    public ZombieType type() {
        return type;
    }

    public String name() {
        return name;
    }

    public Boolean isFasterThan(Zombie z2) {
        // Delegate calculation to strategy enum
        return this.type.isFasterThan(z2.type());
    }

    @Override
    public String toString() {
        return "Zombie " + name;
    }
}

I am sure that this is old hat to you Java folks but, as someone whose mind still thinks natively in C# and Objective-C, this was an exciting little thing to stumble on that literally made my morning. The thing I like about this kind of enum is that it gives me the same kind of warm fuzzy feeling that Scala’s case classes do, but for a different reason.

The moral of the story that applies to more than just C# and Java is this:

Without an open mind, I eliminate the possibility of being pleasantly surprised. If I keep my blinders on and stay within my comfort zone and never explore things, especially those things about which I have made prejudgements, then I am doomed to mediocrity or worse, utter failure.