我有这段代码:
@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();
}
}
该方法获取一个字符串,它是一个Command名称。根据名称,它执行指定的行为。正如你所看到的,它开始有太多的elseifs(并且可能会有更多)。这个方法属于一个在包之间共享的接口,所以我决定把参数作为字符串。有没有更好的方法来避免在有大量命令时这个方法很大(这也包括switch case)?
你可以检查Command
模式https://www.baeldung.com/java-command-pattern但它可能需要相当广泛的重构和使方法inform()
接受Command
类型的对象
您可以使用枚举类,如下所示:
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();
}
然后用以下方法替换上面函数的内容:
@Override
public void inform(String data) {
Command.valueOf(data).invoke();
}
“enum”值的名称必须与您在原始代码中测试的各种内容的字符串值完全匹配(例如C.SubscriptionEvents.WINDOW_CLOSED,C.SubscriptionEvents.WINDOW_CLOSED)
怎么用Enum
而不是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;
}
}
你的代码看起来像这样:
Event.selectEvent(data).accept(this);
你可以用这种方式简化它......
@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();
}
}