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