Constants in Java are a way to avoid anti patterns

  • 2020-04-01 04:31:01
  • OfStack

In applications, we often need a constant file to store Shared constants referenced by multiple places. When designing an application, I encountered a similar situation where many places required various constants.

I'm sure I need a separate file to store these static public constants. But I'm not particularly sure whether to use an interface or a class (enumerations don't meet my needs). I have two choices:

Use interfaces such as:


package one;
public interface Constants {
String NAME="name1";
int MAX_VAL=25;
}
 or 
package two;
public class Constants {
public static final String NAME="name1";
public static final int MAX_VAL=25;
}

My point is to use interfaces. Because the interface automatically sets the member variables to static and immutable (final), this prevents new constants from being added incorrectly in some cases. This also makes the code look simpler and cleaner.

Meanwhile, a simple test showed that the same interface (the bytecode file) took up 209 bytes (on an ubuntu 14.04 machine), while the class (the bytecode file) took up 366 bytes (the same operating system). Fewer bytecode files means less cost to load and maintain. In addition, when the JVM loads the interface, it doesn't need to worry about the additional features provided by the classes (such as reloading, dynamic binding of methods, and so on), so it loads faster.

This looks pretty good, but it's an example of a classic anti-pattern. While using interfaces to hold constants may seem helpful, it leaves a hole for later application extensions.

Suppose it exists in a class that is tightly dependent on these constants. The developer fills the class with references to constants through the interface. Such as:

packagename.Constant.CONSTANT_NAME

So, to "clean up" the code, he might want to implement the interface so he doesn't have to write "packagename.Constants" all over the place, and all the Constants are directly accessible.

However, once he implements the interface, all constants become part of the "contract" (because all constants are public and static). This causes unnecessary constants to be added to the class. This will shake the whole foundation and cause chaos. There is no way in Java to prevent a class from implementing an interface.

Alternatively, we can set the class to final so that it cannot be extended. Even more, we can make the constructor private to prevent instantiation of the class, so that the convention is never broken. In addition, if a particular constant is used multiple times in the same class, developers can use static import.

For all the constant classes, the better design should be:


package three;
//Make the class non-extendable by adding final keywords to avoid inheritance
public final class Constants {
//Hide the constructor
private Constants(){}
public static String NAME="name";
}

Example of static introduction:


import static three.Constants.NAME;
public class UseConstants {
 public static void main(String[] args) {
   System.out.println("the value of constants is"+NAME);
 }
}

This design problem is also known as the Constant Interface anti-pattern.

Above is the use of Java constants in the process of how to avoid anti-pattern solution, I hope to help you learn.


Related articles: