Курсовая по программной инженерии отличается от обычной программной работы тем, что оценивается не только конечный код. Важны требования, архитектура, процесс разработки, тестирование, сопровождаемость и воспроизводимость результата.
Можно написать приложение на несколько тысяч строк и получить слабую инженерную работу, если никто не понимает, как его собирать, где бизнес-логика, что тестируется и как вносить изменения.
Начните с требований
Разделите их на функциональные, нефункциональные и ограничения.
Функциональное требование описывает поведение.
Нефункциональное - качество.
Ограничение может задавать платформу или совместимость.
Не формулируйте всё как «система должна позволять».
Критерий приёмки
Для важного требования сразу напишите, как его проверить.
Например:
«Пользователь может восстановить пароль по подтверждённому адресу».
Критерий:
«После запроса создаётся одноразовая ссылка, старый пароль перестаёт действовать после смены».
Так требование связывается с тестом.
Backlog
Если проект ведётся итерационно, разбейте работу на законченные пользовательские функции.
Не создавайте задачи вида:
- написать backend;
- сделать frontend.
Лучше:
- реализовать создание заказа;
- добавить поиск;
- настроить контроль доступа.
Так легче оценивать прогресс.
Репозиторий
История Git должна показывать развитие проекта.
Не загружайте весь код одним коммитом final.
Хорошие коммиты небольшие, тематические и с понятным сообщением.
Не храните секреты и пароли в репозитории.
Ветки
Для учебного проекта сложный GitFlow не обязателен.
Но полезно отделять экспериментальную работу от стабильной ветки.
Если используется pull request, объясните, какую проверку он обеспечивает.
Не имитируйте корпоративный процесс ради диаграммы.
Архитектурные решения
Для ключевого решения зафиксируйте:
- проблему;
- варианты;
- выбранный вариант;
- последствия.
Например:
«Хранить файлы в БД или объектном хранилище».
Это намного сильнее фразы «была выбрана современная архитектура».
Модульность
Компонент должен иметь понятную ответственность.
Не создавайте класс ManagerServiceHelper, который занимается всем.
Разделение должно помогать тестировать, заменять и понимать код.
Слишком мелкие классы тоже могут ухудшить читаемость.
Зависимости
Смотрите, куда направлены зависимости.
Бизнес-логика не должна без необходимости зависеть от деталей интерфейса.
Если архитектура слоистая, придерживайтесь выбранного направления.
Не рисуйте диаграмму, которая не соответствует импортам в коде.
API
Опишите контракт.
Для важных эндпоинтов укажите:
- вход;
- выход;
- ошибку;
- права.
Не ограничивайтесь фразой «реализован REST API».
Покажите реальный сценарий запроса и ответа.
Обработка ошибок
Не ловите все исключения одним универсальным except с пустым действием.
Разделяйте:
- ошибку пользователя;
- недоступность внешнего сервиса;
- программную ошибку.
Логирование и сообщение пользователю должны быть разными.
Unit-тест
Он проверяет небольшой компонент изолированно.
Хороший unit-тест:
- быстрый;
- детерминированный;
- не требует реальной сети;
- проверяет одно поведение.
Не называйте тестом функцию, которая просто печатает результат.
Integration-тест
Он проверяет взаимодействие компонентов.
Например:
- приложение и БД;
- сервис и очередь;
- два модуля.
Такие тесты медленнее и требуют среды.
Не пытайтесь заменить ими все unit-тесты.
