Reputation: 67
I'm writing a protocol class, which includes a lot of if/elses..here's the class:
public class Protocol {
Scanner scan = new Scanner(System.in);
private static final int WAITING = 0;
private static final int SENTREQUEST = 1;
private static final int SENTITEMS = 2;
private static final int ANOTHER = 3;
private static final int CHOICE = 4;
private int choice;
private int state = WAITING;
public String processInput(String theInput) {
String theOutput = null;
if (state == WAITING) {
theOutput = "Do you accept the terms of agreement? Y/N?";
state = SENTREQUEST;
} else if (state == SENTREQUEST) {
if (theInput.equalsIgnoreCase("y")) {
theOutput = ": 1. program file 2. pictures 3. documentation";
state = CHOICE;
} else {
theOutput = "Invalid Input!";
state = SENTITEMS;
}
}
else if (state == CHOICE) {
choice = scan.nextInt();
switch(choice) {
case 1: theOutput = "show something";
break;
case 2: theOutput = "show something";
break;
case 3: theOutput = "show something";
break;
}
}
else if (state == SENTITEMS) {
theOutput = "Want another? (y/n)";
state = ANOTHER;
} else if (state == ANOTHER) {
theOutput = "Do you accept the terms of agreement? Y/N?";
if (theInput.equalsIgnoreCase("y")) {
theOutput ="test";
state = SENTREQUEST;
} else {
theOutput = "Bye.";
state = WAITING;
}
}
return theOutput;
}
}
It doesn't get to the switch case, and i'm sure it's an issue of breaking out of the if/elses clauses correctly but i can't find the issue.
Upvotes: 0
Views: 6767
Reputation: 2834
Use State pattern like this:
public class Protocol {
Scanner scan = new Scanner(System.in);
private abstract class State { abstract String doit(String theInput); }
private final class WAITING extends State {
String doit(String theInput) {
state = SENTREQUEST;
return "Do you accept the terms of agreement? Y/N?";
}
}
private final class SENTREQUEST extends State {
String doIt(String theInput) {
if (theInput.equalsIgnoreCase("y")) {
state = CHOICE;
return ": 1. program file 2. pictures 3. documentation";
} else {
state = SENTITEMS;
return "Invalid Input!";
}
}
}
//TODO refactoring to State classes for all
// private static final int SENTITEMS = 2;
// private static final int ANOTHER = 3;
// private static final int CHOICE = 4;*/
private int choice;
private State state = WAITING;
public String processInput(String theInput) {
return state.doIt(theInput);
}
}
Upvotes: 0
Reputation: 3486
To solve a similar problem, once I implemented the strategy pattern as an enum. For each strategy, you create a new value for the enum, incapsulating the code in an enum method:
public enum Strategy {
FIRST_STRATEGY {
public String process(String input) {
// Implementation for first strategy
return null;
}
},
SECOND_STRATEGY {
public String process(String input) {
// Implementation for second strategy
return null;
}
};
public abstract String process(String input);
}
You can apply the chosen strategy depending on the enum value you have, actually removing the chain of if/else statements:
Strategy chosenStrategy = Strategy.FIRST_STRATEGY;
String output = chosenStrategy.process(input);
This is a solution I applied for a problem of mine, perhaps it's not the optimal or the more object-oriented one. You have to choose the right solution for your problem, but I hope that my experience can help.
Upvotes: 1