mafalda
mafalda

Reputation: 1024

how can this inner enum code be improved?

I have this construct:

public class Constants {
 enum SystemA implements Marker {
    ConstOne(1), ConstTwo(2), ConstThree(3);
    SystemA(int i)
   {
      number = i;
   }
   int number;
 }

  enum SystemB implements Marker {
    ConstFour(4), ConstFive(5), ConstSix(6);
  SystemB(int i)
   {
      number =i;
   } 
   int number;
 }
}

I have Marker so I can pass to method like this: method(Constants.SystemA) or method(Constants.SystemB)

What is the best way to list all the enum values? I also want to make sure that it is not duplicating the number in any of the enums.

Upvotes: 2

Views: 888

Answers (3)

Costi Ciudatu
Costi Ciudatu

Reputation: 38195

If the contract of the two enums is the same, you can have it into one single enum. However, in order to distinguish the two systems, you can have a separate "SystemType" enum that will contain A, B, ... and you can assign a SystemType to each constant in your System enum.

Furthermore, your SystemType enum can provide an instance method that will return all the systems for a given type, so that you can iterate through only that subset as needed.

As for the numbering, if the sequence is as simple as in your example, you can make use of the ordinal() method of the enum constants so that you'll simply rely on the constant declaration order (perhaps with some math added). Here's what I mean:

public enum SystemType {
    A, B;

    public Set<System> getSystems() {
        Set<System> systems = EnumSet.noneOf(System.class);
        for (System system : System.values()) {
            if (system.getType() == this) {
                systems.add(system);
            }
        }
        // you could also store this result
        // as an instance variable for caching.
        return systems; 
    }
}

public enum System {
    ConstOne(SystemType.A),
    ConstTwo(SystemType.A),
    ConstThree(SystemType.A),
    ConstFour(SystemType.B),
    ConstantFive(SystemType.B);

    private final SystemType systemType;

    private System(final SystemType systemType) {
        this.systemType = systemType;
    }

    public int getNumber() {
        return ordinal() + 1;
    }

    public SystemType getType() {
        return systemType;
    }

}

This is of course useless if you really need to define different contracts for the different system types (methods that only make sense for SystemX or whatever).

P.S.: Of course, System is a really bad name, as it hides the java.lang.System class.

Upvotes: 3

Jochen Bedersdorfer
Jochen Bedersdorfer

Reputation: 4122

Since you are declaring all enums in code, it is your responsibility to provide non-overlapping numbers, if you need this. The more interesting question is: Why would you need this? It smells like you are using enums for things they weren't designed for.

Upvotes: 1

Brian Agnew
Brian Agnew

Reputation: 272257

I would rely on one class - a factory class - to create and control the instances of your System classes.

Upvotes: 0

Related Questions