Написать стековый калькулятор, который принимает в качестве аргумента командой строки имя файла, содержащего команды. Если аргумента нет, то использовать стандартный поток ввода для чтения команд. Использовать вещественные числа.
Реализовать следующий набор команд:
#- строка с комментарием.POP, PUSH- снять/положить число со/на стек(а).+ , - , * , /, SQRT- арифметические операции. Используют один или два верхних элемента стека, изымают их из стека, помещая результат назад.PRINT- печать верхнего элемента стека (без удаления).DEFINE- задать значение параметра. В дальнейшем везде использовать вместо параметра это значение.
Пример (должно вывести 2):
DEFINE a 4
PUSH a
SQRT
PRINT
- Создание команд реализуйте с помощью шаблона проектирования «фабричный метод». Реализация команд не зависит от остальной системы. Остальной код работает только с фабрикой команд и интерфейсами, про конкретные команды ничего не знает.
- Разбор текстового файла с командами и их аргументами реализуйте отдельным классом, который не зависит от остальной системы.
- Загрузку классов команд при создании в фабрике осуществляйте по полному квалифицированному имени класса (включая имя пакета) посредством
Class.forName()с последующим созданием объектов команд методомClass.newInstance(). Фабрика конфигурируется с помощью файла содержащего соответствия между именами команд и классами, реализующими эти команды. Зависимости фабрики от конкретных классов команд (кроме корневого-абстрактного) быть не должно. Файл конфигурации должен храниться рядом с файлом класса-фабрики. - Содержимое стека и именованные параметры передавать команде в виде специального объекта - контекста исполнения. При желании, аргументы команды тоже можно брать из контекста.
- Разработать иерархию исключений, которые будут выбрасывать команды при исполнении. В случае возникновения исключения — выводить информацию об ошибке и продолжать исполнение программы (из файла или команд вводимых с консоли).
- Напишите тесты с использованием JUnit (см. шаблон проекта).