Do Not Create Constant Collection Classes
2016.07.31
Last updated
Was this helpful?
2016.07.31
Last updated
Was this helpful?
Programmers often create separate classes to store constants of a certain area, "to have them at one place" or "to avoid polluting" the procedural classes. But it is not enough to make the code clean. What is the problem with them and how can we solve it?
When new constants have to be created it is not mandatory to add them to the collection class. Developers can decide to add constants to the collection or to create them somewhere else. Unfortunately, this is another problem that makes OOP very hard:
If it is not obvious where to write the new code then the chaos begins.
It breaches the because such classes may contain information for more different functionality.
At a certain point, a class must be tested and finished, in order to have a reliable code. But constant collections are loose and generic, so they are practically never finished. When you look at such a class, you cannot decide whether it is finished or not.
In most cases, it is better to use enums instead of constants. Enums have more benefits over constants:
Enums define and limit a specific value set. So it is clear to which enum a new value has to be added.
They are type-safe. Elements of different value sets are not assignable.
They can be provided with additional useful information. I call it mapping all information that belongs together in one enum constant.
Usually, a constant collection should be split into more than one enum. You can see a clear sign for that in the following cases:
The constants have different types.
The constants' names begin with different prefixes.
Constants are grouped by comments.
With a very simple example, this class is simply a collection of constants:
But it should be refactored to different enums:
At first glance, it seems that the class with the constants is simpler and shorter than the enum classes.
But imagine that it contains hundreds of constants and their number is always growing, while the enums will rarely grow. Actually, the pure informational lines in the enums are only these ones, which are already shorter and more descriptive than the original:
On the other hand, related constants are not declared to be related so you have to pollute your business code with such lines, for example:
Unfortunately, developers tend to write this code in more places in different forms, which means that this business information is implemented more times. It is code duplication. But even if they implement it only once, it is more descriptive in the enum. We should just add some "boilerplate" methods to our enum, which do not repeat the information:
When a set of public constants are written in a class that also contains public procedures, it will lead to the situation, that the class frequently changes only because of the constants.
Of course, constants are only one example. But developers also create classes that hold a collection of independent or loosely coupled methods. The most common example is a service.
A service must provide a public interface, i.e. a set of public methods. To avoid creating a method collection class we should apply the Facade design pattern. So the service class should be "thin" by providing the methods and delegate them to specific, highly cohesive classes.
Indicates that an annotated class is a "Service" (e.g. a business service facade).
Despite that the "magic values" have been transformed into named constants, it may be the incorrect place to define them in the same class.
In the upper example, the ContractService
class is not responsible for defining the constant for the special user ID. It is rather related to User services.
Note: Check out the API documentation of Spring's annotation: