achie
achie

Reputation: 4736

Elegant way to Extend Enums

I have a requirement that is close to extending enums and since that is not possible, after doing some research online, I came up with this approach of using interfaces and making the enums extend them.

My problem is that I have a few basic types A,B and a flag for each type that says if that has to be checked. Similarly I have some extended types C... which do the same stuff after checking their flags.

Here is the code that does this

Type Interface:

public interface Type {

    public String name();

}

Here is the class that uses the basic types

public class BasicChecker {

    private static boolean checkA = false;
    private static boolean checkB = false;

    public enum BasicType implements Type {
        A, B;
    }

    public static boolean isCheckA() {
        return checkA;
    }

    public static void setCheckA(boolean checkA) {
        BasicChecker.checkA = checkA;
    }

    public static boolean isCheckB() {
        return checkB;
    }

    public static void setCheckB(boolean checkB) {
        BasicChecker.checkB = checkB;
    }

    public static void doStuff(String message, Type type) {
        if (type.name().equalsIgnoreCase(BasicType.A.name())) {
            doStuff(message, isCheckA());
        } else if (type.name().equalsIgnoreCase(BasicType.B.name())) {
            doStuff(message, isCheckB());
        }
    }

    protected static void doStuff(String message, boolean flag) {
        if (someCheckMethod() && flag) {
            doStuff(message, flag);
        }
    }

    private static boolean someCheckMethod() {
        return false;
    }
}

And this is the class that uses extended types

public class ExtendedChecker extends BasicChecker {

    private static boolean checkC = false;

    public enum ExtendedType implements Type {
        C;
    }

    public static boolean isCheckC() {
        return checkC;
    }

    public static void setCheckC(boolean checkC) {
        ExtendedChecker.checkC = checkC;
    }

    public static void doStuff(String message, Type type) {
        BasicChecker.doStuff(message, type);
        if (type.name().equalsIgnoreCase(ExtendedType.C.name())) {
            doStuff(message, isCheckC());
        }
    }
}

What I am trying to solve now is to remove all the if else cases from log method. I am also trying to see if there is a better way to do this. Please ignore the statics. I do want them to be static fields and methods.

Upvotes: 1

Views: 111

Answers (2)

jtahlborn
jtahlborn

Reputation: 53694

public class BasicChecker {
  private static final Set<Type> _doCheck = Collections.newSetFromMap(new ConcurrentHashMap<Type,Boolean>());

  public enum BasicType implements Type {
    A, B;
  }

  public static boolean isCheck(Type type) {
    return return _doCheck.contains(type);
  }

  public static void setCheck(Type type, boolean check) {
    if(check) {
      _doCheck.add(type);
    } else {
      _doCheck.remove(type);
    }
  }

  public static void doStuff(String message, Type type) {
    doStuff(message, isCheck(type));
  }
}

Upvotes: 0

sigpwned
sigpwned

Reputation: 7423

I'm having trouble understanding exactly what you're trying to do from your description, but you may find abstract methods in enums to be useful.

For example, you could add an abstract method "foo" to your enums:

public enum BasicType implements Type {
    A {
        public void foo(String message) {
            // Do special A stuff
        } 
    }, B {
        public void foo(String message) {
            // Do special B stuff
        } 
    };

    public abstract void foo(String message);
}

And you could then use that method like this:

public static void doStuff(String message, Type type) {
    type.foo(message);
}

Naturally, you could put any such abstract methods in an interface you extend, if that's useful.

Upvotes: 4

Related Questions