«Наследование и расширяемость систем. Проблемы наследования». «Исключительные ситуации и их обработка. Тестирование исключений».
- Product.java - родительский класс описывающий "продукт".
- Book.java - дочерний класс расширяющий "продукт" родительского класса.
- Smartphone.java - дочерний класс расширяющий "продукт" родительского класса.
- ProductRepository.java - класс-репозиторий.
- ProductManager.java - класс-менеджер.
- ProductRepositoryTest.java - автотесты.
Ветка main с проектом.
- Product.java - с добавленным boolean matcher.
- Book.java - с переопределенным matcher родительского класса.
- Smartphone.java - с переопределенным matcher родительского класса.
- ProductRepositoryTest.java - автотесты.
Ветка rich с проектом.
- NotFoundException.java - генерирующий исключение при попытке удаления несуществующего "продукта".
- AlreadyExistsException.java - генерирующий исключение при попытке добавления "продукта" с повторяющимся id.
- ProductRepositoryTest.java - автотесты.
Ветка expection с проектом.
- Создан Maven проект и настроен pom.xml с плагинами и зависимостями:
- JunitJupier.
- Surefire.
- Lombok.
- Jacoco в режиме генерации отчетов и обрушения сборки по покрытию 100% по бранчам методов.
- Настроен maven.yml для Gitub CI.
- Разрабон базовый класс Product.java - описывающий объект "продукт".
- Разработано два унаследованных от Product.java класса: Book.java, Smartphone.java.
- Реализован класс-репозиторий ProductRepository.java для сохранения, получения сохраненных, удаления экземпляра Product.
- Реализован класс-менеджер ProductManager.java, для добавления экземпляра Product в репозиторий и осуществления поиска по ним.
- Реализован класс с автотестами ProductRepositoryTest.java, проверяющий работу разработанных классов.
- Создана ветка rich от ветки main в которой:
- Добавлен boolean matcher в Product.java, переопределяемый в дочерних классах.
- Добавлены unit тесты в ProductRepositoryTest.java.
- Создана ветка expection от ветки main в которой:
- Создан класс исключения NotFoundException.java, отнаследованный от RuntimeException - используемый в методе removeById() класса ProductRepository.java.
- Создан класс исключения AlreadyExistsException.java, отнаследованный от RuntimeException - используемый в методе saveProduct() класса ProductRepository.java.
- Реализованы автотесты на проверку работы исключений - ProductRepositoryTest.java.
Вам необходимо реализовать менеджер товаров, который умеет:
- добавлять товары в репозиторий,
- искать товары.
Что нужно сделать:
- Разработайте базовый класс
Product
, содержащийID
, название, стоимость. - Разработайте два унаследованных от
Product
класса:Book
с текстовыми полями «название» и «автор» иSmartphone
с текстовыми полями «название» и «производитель»; общие поля вынесите в родителя. - Разработайте репозиторий, позволяющий сохранять
Product
, получать все сохранённыеProduct
и удалять поID
. Для этого репозиторий будет хранить у себя поле с типомProduct[]
(массив товаров). - Разработайте менеджера, который умеет добавлять
Product
в репозиторий и осуществлять поиск по ним. Для этого вам нужно создать класс, конструктор которого будет принимать параметром репозиторий, а также с методомpubliс void add(Product product)
и методом поиска (см. ниже).
Менеджер при переборе всех продуктов, хранящихся в репозитории, должен для каждого продукта вызывать определённый в классе менеджера же метод matches
, который проверяет, соответствует ли продукт поисковому запросу.
При проверке на соответствие запросу товара мы проверяем вхождение запроса в текст названия товара.
Напишите тесты на менеджер и репозиторий, добившись 100% покрытия по бранчам методов с логикой.
Достаточно часто объекты, моделирующие предметную область, называют моделями. Часто модели делают глупыми, то есть не содержащими никакой логики.
Но есть и другой подход, который позволяет делать умные или богатые модели (rich model), которые могут уже содержать определённую логику.
Что нужно сделать:
- Создайте в том же, что и первое задание, репозитории новую ветку
rich
на базе ветки первого задания. - Реализуйте в классе
Product
методpublic boolean matches(String search)
, который определяет, подходит ли продукт поисковому запросу исходя из названия. - Переопределите этот метод в дочерних классах, чтобы они сначала вызывали родительский метод, и только если родительский метод вернул
false
, тогда проводили дополнительные проверки:Book
— по автору,Smartphone
— по производителю. - Замените в менеджере вызов метода
matches
из класса самого менеджера на вызов методаmatches
у самих продуктов:if (product.matches(search)) {
. - Теперь вам нужны unit-тесты на методы ваших умных моделей, напишите их.
- Удостоверьтесь, что ранее написанные тесты на менеджера из решения задачи 1 проходят.
- Добейтесь 100% покрытия по бранчам методов с логикой.
Вы развиваете приложение с менеджером товаров, который мы рассматривали на лекции, и решили сделать так, чтобы при попытке удаления несуществующего объекта из репозитория генерировалось ваше исключение, а не ArrayIndexOfBoundsException
.
Обратите внимание: это правильный подход, поскольку таким образом вы сообщаете через генерацию исключения, что это исключение, вписывающееся в вашу логику, а не ошибка программиста.
Что нужно сделать:
- Возьмите проект с менеджером, репозиторием и товарами, мы его писали в рамках ДЗ про наследование.
- Создайте класс исключения
NotFoundException
, отнаследовавшись отRuntimeException
, и реализуйте как минимум конструктор с параметром-сообщением. Он будет просто вызывать суперконструктор предка, см. подсказку. - В методе удаления
removeById
сначала проверяйте, есть ли элемент. Для этого прямо из методаremoveById
вызывайте методfindById
: если результатnull
, тогда выкидывайте исключениеNotFoundException
. - Напишите два автотеста на репозиторий: первый должен проверять успешность удаления существующего элемента, второй — генерации
NotFoundException
при попытке удаления несуществующего элемента.
Убедитесь, что ваши автотесты проходят. Напоминаем, что проект должен быть на базе Maven, с подключёнными зависимостями и необходимыми плагинами.
Мы рекомендуем вам указывать в сообщении исключения: при удалении по какому конкретно ID было сгенерировано ваше исключение.
Простейший способ, как это можно сделать: "Element with id: " + id + " not found"
.
В том же самом проекте и в той же самой ветке добавьте следующую новую функциональность. В методе добавления нового товара в репозиторий должна осуществляться проверка на то, что в нём уже нет товара, у которого бы совпадал ID
с ID
добавляемого товара. Если же такой есть, то должно выкидываться ваше исключение —
AlreadyExistsException
.
Напишите два автотеста на репозиторий: первый должен проверять успешность добавления элемента, второй — генерации AlreadyExistsException
при попытке добавить элемент с повторяющимся ID
.