{{announcement.body}}
{{announcement.title}}

Why the Constant Interface Pattern Should Be Discouraged

DZone 's Guide to

Why the Constant Interface Pattern Should Be Discouraged

Check out this post to learn more about the constant interface pattern and why it should be discouraged.

· Java Zone ·
Free Resource

It has been an age old practice to place commonly used constants in an interface, and classes implementing it can directly access those constants without prefixing the interface name.

Advantages of This Practice

Advantage Remarks
No need to worry about instantiating a class Constant classes are meant not to be instantiated and hence has a private constructor
Anything??
Access the constants directly with out prefixing a namespace Java static import can be used with classes

Disadvantages of This Practice

Constant Interface Does Not Define a Type

It is considered good practice to segregate the contract (interface defining the type and behavior) from the implementation, and this brings us lots of benefit. Let's consider some examples.

publicclassEmployee implementsPerson {} Employee is a Person and defines behavior specific to Person
publicclassTiger implementsAnimal {}
Tiger is an Animal and defines behavior specific to Animal

However, when we write the following, it really does not make sense. Hence, constant interface, by its very nature, does not define any type.

publicclassTiger implementsSessionContants {} What does it convey? Tiger is a SessionConstants?

Run-Time Issues Because of Field Shadowing


publicinterfaceSessionConstants {
String SESSION_NAME = "XYZ";
}


publicclassHttpSession implementsSessionConstants {

privatestaticfinalString SESSION_NAME = "ABC";

publicstaticvoidmain(String[] args) {
System.out.println(SESSION_NAME);
}
}

What you think the sysout would print?
Is it desirable?


It just works fine with out any warning/error, unlike with Constants class [there would be a warning].
Unless a developer checks any implemented interfaces when adding a constant to a class, or does so but makes a typo in the new constant’s name, the value of a constant can be silently changed.

Namespace Pollution

The named constants appear in the namespace of all implementing classes as well as their sub-classes.

Code Compatibility Issues

If binary code compatibility is required in future releases, the constants interface must remain forever an interface (it cannot be converted into a class), even though it has not been used as an interface in the conventional sense.

Constant Class Approach

The fact that the interface CAN be implemented by an individual, if desired,leaves room for the issues pointed out above. So, it’s best to prevent the ability to implement the interface altogether. Hence, it’s more appropriate to have a final class that can’t be instantiated (with private constructor) at all.

Bad Practice

public interface SessionConstants {
    String COOKIE_NAME = "JSESSIONID";
    String WLS_AUTHCOOKIE_PREFIX = "_WL_AUTHCOOKIE_";
    String DEFAULT_WLS_AUTHCOOKIE = "_WL_AUTHCOOKIE_JSESSIONID";
}


Preferred approach

public final class SessionConstants {
    public static final String COOKIE_NAME = "JSESSIONID";
    public static final String WLS_AUTHCOOKIE_PREFIX = "_WL_AUTHCOOKIE_";
    public static final String DEFAULT_WLS_AUTHCOOKIE = "_WL_AUTHCOOKIE_JSESSIONID";

    private SessionConstants() {
    }
}


Advantages of This Approach

  • Since the required static memebers are imported statically, the class namespace is not polluted.
  • The compiled code has one fewer binary compatibility constraint (that “class implements Constants Interface”).
  • Because static imports apply only to the current file (and not the whole class hierarchy), it is easier to discover where each static member is declared.
  • Run-time and compile-time semantics are more closely aligned when using static imports instead of constants interfaces.
  • If required, static blocks can be declared.

Disadvantages of This Approach

TODO : List out

Constant Interface Pattern and the Rest of the World

Joshua Bloch, in his famous book, Effective Java, talks about it in greater detail:

"The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a non final class implements a constant interface, all of its sub classes will have their namespaces polluted by the constants in the interface."

It is indeed a distasteful use of interfaces, since interfaces should deal with the services provided by an object, not its data. As well, the constants used by a class are typically an implementation detail, but placing them in an interface promotes them to the public API of the class. And hence:

Interfaces should only be used to define contracts and not constants!

Topics:
java ,constant interface pattern ,contracts ,constants ,interfaces ,interface

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}