Java – refactoring and removing case statements when circling over an enum structure

design-patternsjavapolymorphismrefactoringswitch statement

An enum structure declared in its own class is a member variable to the business logic class. That enum basically represents the state of that other class.

Although I have revisited the issue several times, replacing, or getting rid of those case statements proves quite frustrating to me.

Several business logic methods simple iterate over the enum and change the state of that class by assigning another value of the same enum, and other properties.

public enum MyEnum{ A,B,C,D }

The business logic class has this enum as a member:

public class BusinessLogic {

    private MyEnum CurrentSelection;
    private int propertyX;
    private int propertyY;

    public void operation1(){
        switch(CurrentSelection){
        case A: {alter propertyX this way; break;}
        case B: {alter propertyY this way; break;}
        case C: {alter propertyX that way; break;}
        case D: {alter propertyY that way; break;}
        }

    }

    public void operation2(){
        switch(CurrentSelection){
        case A: {CurrentSelection=MyEnum.B; break;}
        case B: {CurrentSelection=MyEnum.C; break;}
        ....etc
        }
    }

    public void operation3(){
        switch(CurrentSelection){
        case A: {CurrentSelection=MyEnum.D; break;}
        case B: {CurrentSelection=MyEnum.A; break;}
        ....etc
        }
    }
}

Another client class will instantiate the business logic class, initialing its properties and then using its operation methods.

What I have successfully done (with help from SO) is encapsulate the operation methods into a command pattern structure so I can call the operations without any case statements. (here).

I guess my trouble is how to encapsulate the case statements in my business logic class. I suspect that I would need polymorphism and the appropriate data structures.

The refactoring experts suggest each case statement should be an implementation of a common interface. But if I have 3 methods iterating over a 4-member enum that means I'd probably need 3 interfaces with 4 implementations each, giving me 12 classes (plus 3 interfaces). Wouldn't that be a class overload? The logic is working fine with those 3 methods as they are, but the issue are the repeating switch/case statements.

Is there a way to refactor those switch statements but avoid a myriad of other classes in the name of polymorphism? Would it be possible to factor out the iterate-over-the-enum part? Or just the cases (where the logic is) should be refactored?


As a first step I removed those methods completely my having them implement a simple interface:

public interface Command {
    void execute();
}

So, its operation method implemented the command interface:

public class Operation1 implements Command {

    private void doOperation1(){
        switch(CurrentSelection){
            ..all the cases here
        }       
    }

    public void execute() {
        doOperation1();
    }

}

As I see this, it will buy my a cleaner business logic class, but the trail of the switch cases will remain, right?

Best Answer

you could include all three methods in an interface and have different implementations of that interface (one for each enum), and have this buisness class delegate the calls..

also for changing the state, have the return value from the operation be that common interface so that upon invoking these methods, the invoking class could return the appropriate object for the next state.