Замените elseif более общим способом - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть этот кусок кода:

@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();
    }
}

Метод получает строку, которая является именем команды. Согласно имени, это делает указанное поведение. Как вы можете видеть, он начинает иметь слишком много elseifs (и, вероятно, будет больше). Этот метод относится к интерфейсу, который разделяется между пакетами, поэтому я решил сделать параметр в виде строки. Есть ли лучший способ сделать это, чтобы избежать большого размера метода, когда будет много команд (в том числе и с переключателем)?

Ответы [ 4 ]

0 голосов
/ 07 сентября 2018

Вы могли бы упростить это таким образом ...

@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();
    } 
}
0 голосов
/ 07 сентября 2018

Как насчет использования 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);
0 голосов
/ 07 сентября 2018

Вы можете использовать класс enum следующим образом:

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)

0 голосов
/ 07 сентября 2018

Вы можете проверить Command шаблон https://www.baeldung.com/java-command-pattern, но это может потребовать довольно обширного рефакторинга и заставить метод inform() принимать объекты типа Command

...