Масштабируемые приложения с Picocli. Вопрос о лучшей практике - PullRequest
0 голосов
/ 07 ноября 2018

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

Я аннотирую свои точки входа с помощью @Command, инициализирую свои аннотированные поля @Parameters и @Option и выполняю логику, которая больше не требует CLI.

На мой взгляд, было бы целесообразно объявить 1 main метод для @Command аннотированного класса, однако я не уверен, что это хорошая идея.

Может быть, нужен какой-то CommandFactory?

Я никогда раньше не создавал CLI-приложений и не использовал picocli, поэтому, если мой мыслительный процесс ошибочен, укажите это.

1 Ответ

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

Вполне нормально иметь отдельный метод main для каждого @Command, который является точкой входа. Метод main необходим, чтобы команда могла быть вызвана автономно из командной строки.

Например:

@Command(name = "hello")
class Hello implements Runnable {
    public static void main(String[] args) {
        CommandLine.run(new Hello(), args);
    }
    public void run() { System.out.println("hello"); }
}

@Command(name = "bye")
class Bye implements Runnable {
    public static void main(String[] args) {
        CommandLine.run(new Bye(), args);
    }
    public void run() { System.out.println("bye"); }
}

Единственное исключение - когда в вашем приложении есть команды с подкомандами . В этом случае вам понадобятся только методы main для команд верхнего уровня, а не для подкоманд.

Пример с подкомандами:

@Command(name = "git", subcommands = {Commit.class, Status.class})
class Git implements Runnable {
    public static void main(String[] args) { // top-level command needs main
        CommandLine.run(new Git(), args);
    }
    public void run() { System.out.println("Specify a subcommand"); }
}

@Command(name = "commit")
class Commit implements Runnable {
    @Option(names = "-m") String message;
    @Parameters File[] files;

    public void run() {
        System.out.printf("Committing %s with message '%s'%n",
                Arrays.toString(files), message);
    }
}

@Command(name = "status")
class Status implements Runnable {
    public void run() { System.out.println("All ok."); }
}

Обратите внимание, что только команда верхнего уровня нуждается в методе main при наличии подкоманд. Даже с подкомандами фабрика не требуется.

...