Don't specify all your constants in a single interface, put them either in the classes they belong to or in specific enums.

Occasionally in old C programming projects you would come across a massive global header file called config.h which had everything including the kitchen sink in it.  But in Java, constants have meaning in the context of the class that owns them.

public interface Constants
{
    public static final int PLAYER_STATE_INACTIVE = 0;
    public static final int PLAYER_STATE_ACTIVE   = 1;
    public static final int PLAYER_STATE_HURT     = 2;
    public static final int PLAYER_STATE_DEAD     = 3;

    public static final int MAX_PLAYERS = 2;

    public static final int AVAILABLE_WORLDS = 57;

    public static final int DIFFICULTY_EASY = 1;
    public static final int DIFFICULTY_HARD = 2;
}

Look closely and you will see that most of the above belong to specific domains or classes.  For example, player state should be closer to the Player class.

public class Player
{
    private int playerState;
    :
    public static final int PLAYER_STATE_INACTIVE = 0;
    public static final int PLAYER_STATE_ACTIVE   = 1;
    public static final int PLAYER_STATE_HURT     = 2;
    public static final int PLAYER_STATE_DEAD     = 3;
    :
}

This approach is perfectly acceptable for small projects and will be understood by most.  

For larger projects with more than one developer there are still some problems with the public static final constant approach because it:

  • Is not typesafe – developers can put any invalid integer into playerState.

  • Doesn't have a namespace so we have to use the PLAYER_STATE prefix.

  • Can be less dependable. If the player state order was changed without recompiling, the game would exhibit unexpected behavior rather than refuse to start.

  • Doesn't dump as text very well; it's just an integer.

So pretty soon you will want to start looking at the enum concept built into the language since JDK 1.5:

public enum PlayerState
{
    INACTIVE,
    ACTIVE,
    HURT,
    DEAD
}

public Player
{
    private PlayerState state = PlayerState.INACTIVE;
    :
}

It's not to say you can't have truly global attributes, such as a DEBUG_MODE flag, but a class with public static final members is fine for that.  There will come a time where you realize your constants need their own namespace.

blog comments powered by Disqus