Разрешить только указанное имя команды, но разрешить дополнительные аргументы - PullRequest
0 голосов
/ 20 февраля 2020

В настоящее время я использую этот код для поиска команды, в которую вводит пользователь:

final Command command = commands.stream()
        .filter(cmd -> input.startsWith(cmd.getName()))
        .findAny()
        .orElseThrow(() -> new InvalidInputException("unknown command"));

Каждый класс команд имеет свой собственный метод getName(). Вот как выглядит метод getName() для ExitCommand():

@Override
public String getName() {
    return "exit";
}

К сожалению, для текущего потока "exittttttt" также принимается. Я не могу использовать .equals(cmd.getName()), потому что есть команды, которые имеют последующие аргументы после имени команды.

Например:

@Override
public String getName() {
    return "delete track";
}

Но полная команда - delete track <id>.

Кто-нибудь знает, как разрешить только имя команды, указанное в каждом методе getName(), но также разрешить дополнительные аргументы?

РЕДАКТИРОВАТЬ:

Каждая команда имеет свой собственный метод getArguments(). Метод вернет 0 для команды exit и 1 для команды delete track. Может быть, это можно использовать для решения этой проблемы?

Ответы [ 4 ]

0 голосов
/ 20 февраля 2020

Я думаю, что добавление совпадений (ввод строки) в класс команд (или интерфейс?) И использование этого метода в Java Stream. Этот способ очень чистый и ориентирован на OOP.

// Abstract?
public abstract class Command {

    public abstract boolean matches(String input);
}

public class ExitCommand extends Command {

    @Override
    public boolean matches(String input) {
        // YOUR logic here
        // You can use regular expression here to validate the input
        return false;
    }
}

public class DeleteTrackCommand extends Command {

    @Override
    public boolean matches(String input) {
        // YOUR logic here:  delete track ...
        // You can use regular expression here to validate the input
        return false;
    }
}

Использование потоков:

final Command command = commands.stream()
        .filter(cmd -> cmd.matches(input))
        .findAny()
        .orElseThrow(() -> new InvalidInputException("unknown command"));
0 голосов
/ 20 февраля 2020

А как насчет этой строки:

final Command command = commands.stream()
        .filter(cmd -> (input.split(" +").length > 0 && input.split(" +")[0].equals(cmd.getName())))
        .findAny()
        .orElseThrow(() -> new InvalidInputException("unknown command"));

?

0 голосов
/ 20 февраля 2020

Ваш дизайн должен быть пересмотрен. Когда мы говорим команду, у нее будут параметры и аргументы. В вашем случае вы комбинируете команду и опцию. Просто отделите их и используйте равно для сравнения команд.

delete -track <id>
  • команда удаления

  • опция track может быть идентифицирована с началом дефиса

  • необязательные аргументы

0 голосов
/ 20 февраля 2020

Если пробел - это то, что всегда отделяет команды от аргументов, то вы можете использовать

.filter(cmd -> (cmd.getArguments() == 0 && input.equals(cmd.getName()))
                 || input.startsWith(cmd.getName() + " "))

. Это проверяет, что входные данные точно соответствуют имени команды, если команда не поддерживает аргументов или если вход имеет команду имя, за которым следует пробел.

Если команды, поддерживающие аргументы, можно вызывать без аргументов, то, возможно, это правильный предикат:

.filter(cmd -> (cmd.getArguments() == 0 && input.equals(cmd.getName()))
                 || input.equals(cmd.getName()) //no args passed
                 || input.startsWith(cmd.getName() + " "))
...