Code Smell: Constants Interfaces

As I am currently refactoring the code of an application created by an insurance company, I will document some code smells I encountered. This way, I will be reminded if I am ever tempted to create such code myself. I’ll begin with constants interfaces, which are a legacy of pre-Enum days and lazy coders.

Constants Interfaces

Constants Interfaces are created in order to save the lazy coder some key strokes. A constants interface is an interface defining nothing but constants and looks like this:

public interface MyConstants {
  public static final String MY_CONSTANT_1 = "foo";
  public static final String MY_CONSTANT_2 = "bar";
  // ...
}

This interface can then be “implemented” by other classes  that need access to the constants. The constants can be used without the prefix “MyConstants.”.

public class MyClass implements MyConstants{
public void doSomething(){
    System.out.println(MY_CONSTANT_1 + MY_CONSTANT_2);
  }
}

Why is this bad? There are several reasons (some of which may be subject to flavor-discussions).

The Code Smell

First of all, interfaces were designed to describe the behavior of a component (i.e. its methods). Thus, an unbiased programmer expects an interface to describe behavior and will be irritated if he only finds constants.

Second, the use of such an interface encourages the habit of simply implementing the interface, even if only one or two of perhaps 50 constants are used. Thus, 48 constants are visible in the implementing class but are not used, which violates encapsulation. Furthermore, if the implementing class is part of a class hierarchy, all subclasses will also have direct access to the constants defined through the interface. In my current refactoring assignment the constants of a single interface were visible in >100 classes of a rather unflexible class hierarchy (which should also be subject to refactoring). Worse: some classes high up in that hierarchy implemented more than one constants interface, making all constants visible in sublasses.

Third, though admittedly a weak argument, using a constant with its class prefix (MyConstants.MY_CONSTANT_1) is more self-documenting than using the constant name alone. Assuming, of course, that the class and constants names are well chosen. If the class prefix is always used, the single advantage of constants interfaces is lost.

Better Solutions

In conclusion, interfaces defining nothing but constants are bad practice and should be avoided. If such interfaces are already present, they should be refactored into either enums or final classes with a private constructor.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s