да, есть более простой/лучший способ, особенно в Java или других языках OO.
Основная идея, во-первых, заключается в том, что ваш анализатор команд представляет собой конечный автомат: состояние START — это пустая строка (или индекс в начале строки).
Давайте подумаем о echo
:
$ echo foo bat "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
.
Обновлять
Это может быть немного слишком общим, поскольку используется шаблон Factory. Зачем заводской метод? В основном вы использовали бы это, чтобы каждый раз, когда вы выполняете команду, объект «глагол» (например, экземпляр Echo
) мог иметь свое собственное внутреннее состояние. Если вам не нужно, чтобы состояние сохранялось в течение длительного времени, вы можете упростить это до
(cmds.get(tok)).doThis(nouns);
Теперь он просто получает и использует объект Echo
, созданный вами при его создании с помощью cmds.add("echo", new Echo());
.
person
Charlie Martin
schedule
04.04.2009