Калькулятор 2.0 Школа 21
Пробую опубликовать эту статью второй раз, потому что доверился Хабру на счет хранения статей, но в итоге оказалось, что даже опубликованные статьи Хабр сначала модерирует, а после удаляет, если они не прошли модерацию… Придётся выделить ещё пару часов на статью. Сам калькулятор 2.0 — это учебный проект Школы 21 в Казани и это один из первых проектов на C++. Приступим
Зачем?
- Узнать что такое паттерн MVC.
- Углубиться в ООП
- Усовершенствовать калькулятор 1.0
Как это было?
Взглянув на первый калькулятор на Си сразу отметил дизайн. Дизайн калькулятора менять не буду, основа точно на нём. Однако сам принцип работы точно пришлось поменять, он работает с ошибками и не так как нужно. Даже не знаю как его сдал впервые)
Нашел классный калькулятор на просторах интернета desmos некоторые фитчи заберу.
Понимание MVC
Долго спорили с пирами о пониманиии паттерна MVC и в итоге у каждого своё понимание данного паттерна. Кто-то считает, что во View необходимо создавать экземпляр класса Controller и обращаться к этим функциям, но мое мнение, исходя из блок схемы:
- Пользователь общается только с UI
- View обращается к Controller только через сигналы и приватные слоты, то есть не создает экземпляры классов внутри
- Controller по сигналам (нажатиям пользователя) вызывает методы Model и модифицирует View исходя из полученных результатов
- Model содержит в себе всю бизнес-логику, где она расчитывается и меняет состояния, опять же в Model нет обращений к объектам класса Controller
Поближе к коду
Изначально решил полностью переписать конвертер входящего выражения из инфиксной в постфиксную нотацию, но целый месяц потратил на поиск ошибок в коде. Основная ошибка — это довериться к чату GPT) Ошибки в коде не было. Просто напросто вычисления проверял на калькуляторе desmos, который вычисляет тригонометрические функции в градусах, а функции библиотеки в радианах))) Странно что несколько пиров, которых приглашал посмотреть на код и указать ошибку так и не заметили ничего...
Парсер+валидатор
Попытка совместить парсер с валидатором провалилась. Изначально строка которая приходила от пользователя проставляла между операторами, функциями и числами пробелы, чтобы удобно было класть в контейнер уже отделенные токены:
далее с помощью регулярных выражений проверялся каждый элемент, но проблема в том, что возможны повторения элементов или неправильный порядок элементов.
Эта идея хорошая, имеет свои плюсы, но на данной стадии не подходит.
Инфикс ту постфикс посимвольно
В первой версии калькулятора конвертер был реализован посимвольно (char), поэтому решил вернуться к этому рабочему варианту, но переписать заново и без встроенной валидации. Валидацию выражения оставил на "десерт".
Главное - работает!
Рефакторинг в MVC
Всё готово (кроме валидатора) теперь пришло время подключить модуль построения графика, депозитный и кредитный калькуляторы. Но не так всё просто)
Ниже код main.cpp который отражает понимание паттерна MVC
Класс View выглядит так:
Класс Controller:
Класс Model обычный независимый класс, который содержит все функции в теле, есть недостаток этого класса - антипаттерн класс-бог. Класс содержит в себе функции для расчета графика, депозитного и кредитного калькулятора. Хотя для масштабирования проекта необходимо разделить на несколько классов.
Проблемы
1. Большой проблемой с которой столкнулся - это передача параметров UI в класс Model для расчетов. У моих функций много аргументов и не соблюдается принцип один вход - один выход. По сути void функции меняют значения в структурах данных. Это выглядит некрасиво и пока не хватает опыта как сделать так чтобы функции либо наследовались от базового класса либо виртуально перегружались.
Оставим эту проблему на следующую версию калькулятора.
2. Обнаружен баг - депозитный калькулятор не считает при добавлении внесений или снятий.
Думаю это происходит из-за этой неуклюжей функции, которую решил совместить для снятий и внесений. Надо будет разобраться почему так происходит.
3. Калькулятор и тесты медленно собираются, потому что внутри всех файлов используется массивная библиотека QT. Причем для сборки тестов использую Cmake а для сборки самого калькулятора Qmake
4. Большая ошибка с графиком функций. Неверно расчитывается область определения! Эту ошибку исправил, но произошел сбой в компьютерах школы и пришлось откатить версию коммита, так что в конечный результат это исправление не попало... И ещё, если изменение по оси Х встроено в интерфейс, то по оси Y нет изменения, хотя на одной из проверок узнал что qcustomplot поддерживает масштабирование колесиком мышки.
5. Валидация - огромная проблема, не смогу написать правильный валидатор, поэтому peer to peer предложил использовать готовую библиотеку exprtk.hpp с встроенной валидацией, осторожно, это
6. Code Review и Google Style - ошибки стиля кода и логика кода.