2014-12-27 2 views
1

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

В результате объект команда может выглядеть следующим образом:

public class CommandA implements Command { 
    ReceiverA receiverA; 

    public CommandA(RecieverA receiverA) { 
     this.receiverA = receiverA; 
    } 

    @Override 
    public void execute() { 
     Scanner scanner = new Scanner(System.in); 

     String x = scanner.nextLine(); 

     receiverA.methodA(x); 

    } 
} 

Я обнаружил отсутствие примеров, так что я задавался вопросом, было ли это «хорошо» практике, как и в примерах, которые я видел объект команды просто использует метод приемника.

+1

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

ответ

1

Надеемся, что пользователь вводит прямо вперед, чтобы библиотека для синтаксического анализа командной строки или простой сгенерированный парсер с использованием грамматики BNF удаляла класть в клиентскую логику распознавания ввода.

Сила шаблона команды заключается в том, что клиент может откладывать выполнение команды или ряда команд и разрешать клиенту передавать команды вызывающему по своему выбору.

Возьмем, к примеру, какую-то систему, которая предоставляет CLI и выполняет некоторые манипуляции с данными. Предположим, вы хотите смоделировать некоторые пользовательские операции: «save-all» и «print-sample». Каждой из этих команд могут отсутствовать некоторые требуемые данные, которые пользователь должен предоставить. Предположительно, у них также есть другие варианты с дефолтами. Вы должны использовать синтаксический анализ командной строки, чтобы отделить пользовательский ввод, предоставленный через командную строку, а затем обернуть или извлечь обработанные фрагменты в командные экземпляры SaveAll или PrintSample. Логика клеев будет состоять только в том, чтобы использовать правильный тип команды. Ваш код будет вдоль линий:

String[] userInput = ... 
Parsed parsedInput = parser.parse(userInput) 
Command command; 
switch (parsedInput.getCommandName()) { 
    case 'save-all': 
    command = new SaveAll(parsedInput); 
    break; 
    ... 
} 

Если вы используете правильный инструмент, возможно, вы можете отказаться даже этот клей код; см. JCommander для Java/Scala.

После того как вы разделили озабоченность для разделения на части пользовательского ввода, ваши классы команд будет предоставлена ​​разобран ввода, например:

public class SaveAll implements Command { 
    private String targetName; 
    private char separator = ',' 

    private DataSet dataset; 
    private Filesystem filesystem; 

    public SaveAll(Parsed input) { 
    targetName = input.getTargetName(); 
    if (input.getSeparator() != null) { 
     separator = input.getSeparator(); 
    } 
    } 

    @Injected 
    public void setDataSet(...) { ... } 

    @Injected 
    public void setFilesystem(...) { ... } 

    public void execute() { 
    try (Datafile file = filesystem.openForWrite(targetName)) { 
     for (Row row : dataset.rows()) { 
     file.writeRow(row, separator); 
     } // rows loop 
    } // auto-resource 
    } // end execute() 
} 

Наконец, в этом примере, клиент (инструмент, который открыли CLI пользователю) могут позволить пользователям подключаться к различным системам. И под ним будет иметь invoker для каждой системы. Следовательно, команда будет передана соответствующему счетчику. (И это Вызывающий вполне может сериализовать или очереди команды.)

+0

Замечательно, что вы использовали конкретную команду в своем примере. Однако что произойдет, если вход содержит ошибку, например, targetName является недопустимым файлом и вызывает исключение при выполнении? Не будет ли более надежная проверка дизайна действительными данными перед вызовом execute? – Fuhrmanator

0

Использование UML определения исходного рисунка в GoF:

UML diagram of the Command pattern

Я думаю, ответ на который обрабатывает входные данные? находится в эквиваленте класса Invoker (или класса, который его вызывает).

Это определенно не ConcreteCommands, потому что намерение состоит в том, чтобы в конечном итоге отменить или повторить команды. Повторный вызов (последовательные вызовы execute()) не будет работать, если он полагался на разбор входных данных в методе execute().

Командный объект нуждается в минимальном количестве информации для выполнения своей работы.Это означает, что он должен знать объект Receiver (который может отличаться для каждой команды) и, возможно, некоторые параметры команды. Я бы не обрабатывал ввод (даже после его анализа) вообще внутри ConcreteCommand.

 Смежные вопросы

  • Нет связанных вопросов^_^