Search code examples
javacoding-stylemaintainability

How to maintain enums (and adding new values) in a very large codebase


In a very large and old codebase, suppose we're using a database column status with enum values as NEW, IN_PROGRESS, COMPLETED, REJECTED.

Now this status is used in multiple conditions in code like

if (status == `NEW` || status ==  `IN_PROGRESS`) {
  // do something
}

or might be in some SQL statement like

WHERE status NOT IN ("REJECTED")

Now if we want to add a new enum value to status eg. "CANCELLED", then we'd have to handle all the places where status was used in the code.

Considering that the codebase can be somewhat distributed, large and quite old, it would prove to be very difficult for this sort of change. How can we improve this such that it would be easier to maintain these sort of changes?

I'm not writing about any particular language, just the concept, as it should be replicable for multiple languages.


Solution

  • is this Java or JavaScript? anyway, you should be able to add some polymorphic behavior into your enum. This means each type of the enum knows how to do something or if it allows doing something. let's look at a simple Java example:

    public enum Status {
        NEW(true),
        IN_PROGRESS(true),
        REJECTED(false);
    
        private final boolean allowsSomething;
    
        Status(boolean allowsSomething) {
            this.allowsSomething = allowsSomething;
        }
    
        public boolean allowsSomething() {
            return allowsSomething;
        }
    }
    

    Now, let's refactor your method. Instead of this:

    void someMethod() {
        Status status = someStatus();
        if (status == Status.NEW || status == Status.IN_PROGRESS) {
            // do something
        }
    }
    

    We'll use it like this:

    void someMethod_refactored() {
        Status status = someStatus();
        if (status.allowsSomething()) {
            // do something
        }
    }
    

    Let's assume you now want to add an additional value to the enum, for example, CANCELLED. You will be forced to specify the allowsSomething flag, and then all the clients of this enum will work correctly.