Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: refactoring static constants

We are in the process of refactoring some code. There is a feature that we have developed in one project that we would like to now use in other projects. We are extracting the foundation of this feature and making it a full-fledged project which can then be imported by its current project and others. This effort has been relatively straight-forward but we have one headache.

When the framework in question was originally developed, we chose to keep a variety of constant values defined as static fields in a single class. Over time this list of static members grew. The class is used in very many places in our code. In our current refactoring, we will be elevating some of the members of this class to our new framework, but leaving others in place. Our headache is in extracting the foundation members of this class to be used in our new project, and more specifically, how we should address those extracted members in our existing code.

We know that we can have our existing Constants class subclass this new project's Constants class and it would inherit all of the parent's static members. This would allow us to effect the change without touching the code that uses these members to change the class name on the static reference. However, the tight coupling inherent in this choice doesn't feel right.

before:

public class ConstantsA {
  public static final String CONSTANT1 = "constant.1";
  public static final String CONSTANT2 = "constant.2";
  public static final String CONSTANT3 = "constant.3";
}

after:

public class ConstantsA  extends ConstantsB { 
  public static final String CONSTANT1 = "constant.1";
}

public class ConstantsB {
  public static final String CONSTANT2 = "constant.2";
  public static final String CONSTANT3 = "constant.3";
}

In our existing code branch, all of the above would be accessible in this manner:

ConstantsA.CONSTANT2

I would like to solicit arguments about whether this is 'acceptable' and/or what the best practices are.

like image 763
akf Avatar asked Apr 09 '26 09:04

akf


1 Answers

  • A class with only static fields is a code smell. It's not a class.

  • Some people use interfaces, so they can implement it to use the constants more easily. But an interface should be used only to model a behaviour of a class. (http://pmd.sourceforge.net/rules/design.html#AvoidConstantsInterface) Using static imports from Java 5 removes the need for simple constant usage at all.

  • Are your constants really Strings, or just used as Strings. If they are different options for some type (so called enumerations), you should used typesafe enumerations, using enum in Java 5 or the Enum provided by Commons Lang. Of course, converting your code to use enums might be a little work.

  • You should at least split the constants to groups of related constants in files with proper business name. Moving the final members is easy in IDE and will update all usages.

  • If you can afford it, convert them to enums then. (Think about using about a script to do that, often it's possible.) Class hierarchies are only usefull, if there is a relation between the constants/enums. You can keep the Strings if you have to but still think about them as entities, then extends might make sense for some (describing is-a relation). First enums can be simple classes made by yourself if serializing is not a problem. Enums are always favourable due to their type safe nature and the extra name showing intend or business/domain specific things.

  • If the constants are really String constants use a Properies or ResourceBundle, which can be configured by plain text files. Again you can script the refactoring using the constant names as resource bundle keys and generate both files automatically.

like image 200
Peter Kofler Avatar answered Apr 10 '26 23:04

Peter Kofler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!