Да, есть более простой / лучший способ, особенно в Java или других языках OO.
Основное понимание, во-первых, заключается в том, что ваш анализатор команд является конечным автоматом: состояние START - это пустая строка (или индекс в начале строки).
Давайте подумаем о echo
:
$ echo foo bat "bletch quux"
разбить строку на части:
"echo" "foo" "bar" "bletch quux"
в оболочке, грамматика обычно глагол существительное существительное существительное ... так что интерпретируйте это так. Вы МОЖЕТЕ сделать это с последовательностью if-else if, но хеш лучше. Вы загружаете хеш со строками в виде индексов и индексируете что-то еще. Это может быть просто число, которое войдет в коммутатор:
(это псевдокод):
Hashtable cmds = new Hashtable();
enum cmdindx { ECHO=1, LS=2, ...}
cmds.add("echo", ECHO); // ...
// get the token into tok
switch (cmds.get(tok)) {
case ECHO: // process it
// get each successor token and copy it to stdout
break;
...
default:
// didn't recognize the token
// process errors
}
ДАЖЕ лучше, вы можете применять шаблоны Command и Object Factory. Теперь у вас есть класс Command
public interface Command {
public void doThis(String[] nouns) ;
public Command factory();
}
public class Echo implements Command {
public void doThis(String[] nouns){
// the code is foreach noun in nouns, echo it
}
public Command factory(){
// this clones the object and returns it
}
}
Теперь ваш код становится
// Load the hash
Hashtable cmds = new Hashtable();
cmds.add("echo", new Echo()); // one for each command
// token is in tok
// the "nouns" or "arguments are in a String[] nouns
((cmds.get(tok)).factory()).doThis(nouns);
Видите, как это работает? Вы ищите объект в хэше. Вы вызываете метод factory
, чтобы получить новую копию. Затем вы вызываете обработку для этой команды, используя метод doThis
.
Обновление
Это может быть немного слишком general, поскольку он использует шаблон Factory. Почему фабричный метод? В основном, вы должны использовать это так, чтобы каждый раз, когда вы выполняете команду, объект «глагол» (например, экземпляр Echo
) мог иметь свое собственное внутреннее состояние. Если вам не нужно сохранять состояние в течение длительного времени, вы можете упростить это до
(cmds.get(tok)).doThis(nouns);
Теперь он просто получает и использует Echo
объект, который вы создали, когда создали его с помощью cmds.add("echo", new Echo());
.