2

Currently an enum in our project takes properties in the constructor. They are practically guaranteed to be entirely different across every different enum.

Now I'd like to add an property which is a simple boolean - and it's only different from the default in a very few specific cases.

There's 2 sensible approaches I can see here:

  1. Refactor the constructor to take the boolean parameter, set it to true for the specific necessary ones. While this is the most consistent one with the current status quo, it also adds imho quite a bit of unnecessary clutter since it varies from the default so rarely.

  2. Define an overridable getter Method that uses the default and override the method in the enums where it varies. I like this because it keeps the constructor "clean", but it starts introducing "magic" that might be missed or forgotten by successors in the future - especially since it hides the implementation.

Judging purely by clarity of implementation, option #1 should win by far. But my gut is not sure whether clairty can be sacrificed in this case for a little bit of extra readability.

5
  • an enum with constructors and properties?
    – Ewan
    Commented Feb 4, 2020 at 11:06
  • 3
    cant you have a default optional parameter on the constructor, or overloaded constructors?
    – Ewan
    Commented Feb 4, 2020 at 11:19
  • 3
    Why not just overload the constructor with another version that takes the boolean as well? See this. Commented Feb 4, 2020 at 11:24
  • I was thinking having overloaded constructors too, but I'd be tempted to say they may have the same issue that #2 has that they could be "forgotten"... although to be fair, there's only so much you can do at some point
    – Joe
    Commented Feb 4, 2020 at 11:26
  • 1
    I don't think that's a realistic issue - they will be right next to each other in code, the implementation isn't really hidden, and (if I'm not mistaken) the IDE should present the user with both. What you have here is less of a traditional enum (enumerated constants), and more of a proper class that happens to provide a way to get a finite number of predefined instances. In a different language, you'd model that by making the constructors private, and providing a number of static methods (or properties) that supply the predefined values. This is the same thing, just in a Java flavor. Commented Feb 4, 2020 at 11:32

1 Answer 1

2

Depending on your needs and on the actual meaning of the boolean, there are some other options that come to my mind:

  1. (From the comments to the question - repeated for completeness): Override the constructor. Most enum values use the one without boolean, the special ones use the one with boolean. While this avoids the clutter for the bigger part of your enum values, it adds a "mysterious boolean" to some of them.
  2. (Variant of 1., combinable with 3.): Instead of adding a boolean parameter, introduce another enum with two values, let say SPECIAL and NON_SPECIAL (please find better names for them). This way you at least don't have the mysterious boolean in the parameter list. Also your IDE allows you to search for usages of SPECIAL and thus find the "special" values quickly. Of course this adds even more "unnecessary clutter".
  3. Maybe the boolean tells you that this enum should really be two distinct enums?
  4. You could add a Set of enum values as a static member and in the getter check if the value is contained in this set:

    enum MyEnum {
        VALUE1/*(...)*/,
        VALUE2/*(...)*/,
        // ...
        VALUE7/*(...)*/;
    
        // The Collections.unmodifiableSet(...) is optional but I like it to not
        // accidentally modify the set.
        private static Set<MyEnum> SPECIAL_VALUES =
                Collections.unmodifiableSet(EnumSet.of(VALUE2, VALUE7));
    
        // fields, constructor and other methods...
    
        public boolean isSpecial() {
            return SPECIAL_VALUES.contains(this);
        }
    }
    

    (I hope your naming is better than this 😉)

    This way nothing is hidden, the definition of "special" is still in the enum and you can find out quickly which enum values are "special". You can even make the Set public (or provide a static getter for it) to allow quick access to all "special" values at once.

    You can even add more boolean values (= more Sets) without loosing clarity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.