Какой шаблон или метод использовать при вызове метода проверки регулярных выражений в нескольких операторах if? - PullRequest
0 голосов
/ 13 июня 2018

Я создал фабричный шаблон в своем классе.

В этом классе я внедрил классы, которые реализуют интерфейс Command на основе входящего параметра String.

Заводской класс

@Component
@RequiredArgsConstructor
public class CommandFactory {
    private final ACommand aCommand;
    private final BCommand bCommand;
    private final CCommand cCommand;
    private final DCommand dCommand;
    private final ECommand eCommand;
    private final FCommand fCommand;

    public Command createCommand(String content) {
        if (aCommand.isMatching(content)) {
            return aCommand;
        } else if (bCommand.isMatching(content)) {
            return bCommand;
        } else if (cCommand.isMatching(content)) {
            return cCommand;
        } else if (dCommand.isMatching(content)) {
            return dCommand;
        } else if (eCommand.isMatching(content)) {
            return eCommand;
        } else if (fCommand.isMatching(content)) {
            return fCommand;
        } else {
            return null;
        }
    }

В isMatching() Существуют разные регулярные выражения, и я пытаюсь выяснить, как обрабатывать эту входящую строку.

Я ищу более чистый способ избавиться от этих последовательных операторов if.Потому что всякий раз, когда я создаю новый класс в этой фабрике, я добавляю другой оператор if.

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Если вы хотите избавиться от последовательных операторов if, вы можете использовать потоки (например, предложенный пользователь Sweeper ) или циклы, и я бы также предложил вернуть и необязательный, что делает обработку null более понятной дляclient.

Вот два предложенных варианта избавления от if else повторений, один с циклами, другой с потоками:

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class CommandPatternExample {

    private List<Command> candidates = Arrays.asList(new ACommand(), new BCommand(), new CCommand());

    public Optional<Command> createCommand(String content) {
        for(Command command : candidates) {
            if(command.isMatching(content)) {
                return Optional.of(command);
            }
        }
        return Optional.empty();
    }

    public Optional<Command> createCommandStream(String content) {
        return candidates.stream().filter(c -> c.isMatching(content)).findFirst();
    }
}

interface Command<T> {
    void execute(T obj);
    boolean isMatching(String s);
}

class ACommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "A".equals(s);
    }
}

class BCommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "B".equals(s);
    }
}

class CCommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "C".equals(s);
    }
}
0 голосов
/ 13 июня 2018

Карта может быть хорошей идеей.Это означает, что если вы поместите свои экземпляры команд на карту как значения, где ваш ключ будет чем-то, что вы можете сопоставить с входящей строкойТогда вместо последовательного поиска с эффективностью O (n) вы можете получить гораздо лучшую производительность O (1).Это короткий ответ.

Кроме того, существует библиотека Java с открытым исходным кодом MgntUtils (написанная мной), которая содержит некоторую утилиту под названием «Самоинстанцирующие фабрики». В основном она управляет вами и фабрикой для вас.Все, что вам нужно сделать, это создать класс, который реализует определенный интерфейс, и утилита добавит его для вас в фабрику, основанную на карте.Это может быть полезно для вас.Вот ссылка на статью, которая объясняет об утилитах в библиотеке, а также о том, где взять библиотеку (Github и Maven central).В статье ищем абзац " Управление жизненным циклом (самоинстанцирующие фабрики) ".Также библиотека поставляется с подробным письменным javadoc и примером кода для этой функции.

0 голосов
/ 13 июня 2018

Может быть, Stream может помочь?

Stream<Command> stream = Stream.of(aCommand, bCommand, cCommand ...);
return stream.filter(x -> x.isMatching(content)).findFirst().orElse(null);

Теперь каждый раз, когда вы добавляете новый класс, вы просто добавляете новый объект в первую строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...