Reputation: 475
I have this piece of code:
@Override
public void inform(String data) {
if (data.equals(C.SubscriptionEvents.WINDOW_CLOSED)) {
File tempFolder = new File("temp");
File[] files = tempFolder.listFiles();
if (files != null) {
for (File f : files) f.delete();
}
} else if (data.equals(C.Controller.Commands.SELECT_MODE_VERTICES)) {
MainModel.setCurrentMode(Mode.VERTICES);
display.getInfoSection().repaint();
} else if (data.equals(C.Controller.Commands.SELECT_MODE_LINES)) {
MainModel.setCurrentMode(Mode.LINES);
display.getInfoSection().repaint();
} else if (data.equals(C.Controller.Commands.SELECT_MODE_SECTORS)) {
MainModel.setCurrentMode(Mode.SECTORS);
display.getInfoSection().repaint();
}
}
The method gets a string which is a Command name. According to the name, it does a specified behavior. As you can see, it starts to have too much elseifs (and probably will have more). This method belongs to an interface which is shared between packages so I decided to make the parameter as string. Is there a better way to do it to avoid the method to be huge when there will be lots of commands (this includes switch case too)?
Upvotes: 2
Views: 120
Reputation: 26
You could simplify it this way...
@Override
public void inform(String data) {
Map<String, String> map = new HashMap<String, int>();
map.put(C.Controller.Commands.SELECT_MODE_VERTICES, Mode.VERTICES);
map.put(C.Controller.Commands.SELECT_MODE_LINES), Mode.LINES);
map.put(C.Controller.Commands.SELECT_MODE_SECTORS, Mode.SECTORS);
if (data.equals(C.SubscriptionEvents.WINDOW_CLOSED)) {
File tempFolder = new File("temp");
File[] files = tempFolder.listFiles();
if (files != null) {
for (File f : files) f.delete();
}
} else if (map.containsKey(data)) {
MainModel.setCurrentMode(map.get(key));
display.getInfoSection().repaint();
}
}
Upvotes: 0
Reputation: 18245
What about to use Enum
instead of if...else
?:
enum Event {
NULL(null, context -> { }),
WINDOWS_CLOSE(C.SubscriptionEvents.WINDOW_CLOSED, context -> {
File tempFolder = new File("temp");
File[] files = tempFolder.listFiles();
if (files != null) {
for (File f : files) f.delete();
}
}),
SELECT_MODE_VERTICES(C.Controller.Commands.SELECT_MODE_VERTICES, context -> {
MainModel.setCurrentMode(Mode.VERTICES);
display.getInfoSection().repaint();
}),
SELECT_MODE_LINES(C.Controller.Commands.SELECT_MODE_VERTICES, context -> {
MainModel.setCurrentMode(Mode.LINES);
display.getInfoSection().repaint();
}),
SELECT_MODE_SECTORS(C.Controller.Commands.SELECT_MODE_SECTORS, context -> {
MainModel.setCurrentMode(Mode.SECTORS);
display.getInfoSection().repaint();
});
private final String id;
private final Consumer<Foo> consumer;
Event(String id, Consumer<Foo> consumer) {
this.id = id;
this.consumer = consumer;
}
public final void accept(Foo context) {
consumer.accept(context);
}
public static Event selectEvent(String data) {
for (Event event : values())
if (event.id.equals(data))
return event;
return NULL;
}
}
And your code will be look like this one:
Event.selectEvent(data).accept(this);
Upvotes: 0
Reputation: 537
You could use an enum class, as follows:
public enum Command {
WINDOW_CLOSED { //C.SubscriptionEvents.WINDOW_CLOSED
public void invoke() {
File tempFolder = new File("temp");
File[] files = tempFolder.listFiles();
if (files != null) {
for (File f : files) f.delete();
}
}
}
,SELECT_MODE_VERTICES { // C.Controller.Commands.SELECT_MODE_VERTICES
public void invoke() {
MainModel.setCurrentMode(Mode.VERTICES);
display.getInfoSection().repaint();
}
}
,SELECT_MODE_LINES { // C.Controller.Commands.SELECT_MODE_LINES
public void invoke() {
MainModel.setCurrentMode(Mode.LINES);
display.getInfoSection().repaint();
}
}
,SELECT_MODE_SECTORS { // C.Controller.Commands.SELECT_MODE_SECTORS
public void invoke() {
MainModel.setCurrentMode(Mode.SECTORS);
display.getInfoSection().repaint();
}
}
;
public abstract void invoke();
}
Then replace the guts of your function above with this:
@Override
public void inform(String data) {
Command.valueOf(data).invoke();
}
The names of your 'enum' values must exactly match the string values of the various things you are testing for in your original code (e.g. C.SubscriptionEvents.WINDOW_CLOSED, C.SubscriptionEvents.WINDOW_CLOSED)
Upvotes: 0
Reputation: 8758
You can check Command
pattern https://www.baeldung.com/java-command-pattern but it may require quite extensive refactoring and make method inform()
accept objects of type Command
Upvotes: 3