В качестве результата пришлите ссылки на ваши GitHub-проекты в личном кабинете студента на сайте netology.ru.
Все задачи этого занятия можно делать в одном репозитории.
Важно: если у вас что-то не получилось, то оформляйте Issue по установленным правилам.
Вы можете делать все задачи этого занятия в одном репозитории (если делаете их в разных ветках).
- Ознакомьтесь с особенностями Lombok при использовании наследования
- Ознакомьтесь с доп.материалами о
staticиreflection - Инициализируйте на своём компьютере пустой Git-репозиторий
- Добавьте в него готовый файл .gitignore
- Добавьте в этот же каталог необходимые файлы (
pom.xml) - Сделайте ветки для первой задачи (после того, как сделаете первую задачу, на её основе создайте ветку для второй задачи)
- Создайте публичный репозиторий на GitHub и свяжите свой локальный репозиторий с удалённым
- Сделайте пуш (удостоверьтесь, что ваш код и обе ветки появились на GitHub)
- Ссылку на ваш проект отправьте в личном кабинете на сайте netology.ru
- Задачи, отмеченные как необязательные, можно не сдавать, это не повлияет на получение зачета (в этом ДЗ все задачи являются обязательными)
На основании проекта из лекции необходимо реализовать менеджер товаров, который умеет:
- Добавлять товары в репозиторий
- Искать товары (репозиторий должен отдать все товары, а менеджер уже потом по ним ищет*)
Примечание*: это не самый эффективный способ. Когда мы будем проходить базы данных, поговорим, что это лучше делать там (ещё лучше - воспользоваться специализированным решением).
Что нужно сделать:
- Разработайте базовый класс
Product, содержащийid, название, стоимость - Разработать два унаследованных от
Productкласса:Book(с полями название* и автор) иSmartphone(с полями название* и производитель) - Разработайте репозиторий, позволяющий сохранять
Product'ы, получать все сохранённыеProduct'ы и удалять поid - Разработайте менеджера, который умеет добавлять
Product'ы в репозиторий и осуществлять поиск по ним
Примечание*: надеемся, вы догадались, что название итак уже есть в классе Product
У менеджера должен быть метод searchBy(String text), который возвращает массив найденных товаров
public class ProductManager {
// добавьте необходимые поля, конструкторы и методы
public Product[] searchBy(String text) {
// ваш код
}
public boolean matches(Product product, String search) {
// ваш код
}
}Менеджер при переборе всех продуктов, хранящихся в репозитории, должен для каждого продукта вызывать собственный метод matches, который проверяет, соответствует ли продукт поисковому запросу.
Проверку соответствия проводится с помощью instanceof - для книги по полям название и автор, для смартфона по полям название и производитель.
Пример того, как это можно сделать:
if (product instanceof Book) {
Book book = (Book) product;
if (book.getName().equalsIgnoreCase(search)) {
return true;
}
if (book.getAuthor().equalsIgnoreCase(search)) {
return true;
}
return false;
}Q: Откуда взять информацию о методе equalsIgnoreCase?
A: Вам нужно посмотреть документацию на класс String* (ведь book.getName() возвращает объект класса String) и подобрать необходимые методы (на ваше усмотрение). Это очень важно: знать какие классы есть в стандартной библиотеки и какие методы они предоставляют!
Примечание*: воспринимайте пока CharSequence как String.
Подсказка
public class ProductManager {
// добавьте необходимые поля, конструкторы и методы
public Product[] searcyBy(String text) {
Product[] result = new Product[0];
for (Product product: repository.findAll()) {
if (matches(product, text)) {
Product[] tmp = new Product[result.length + 1];
// используйте System.arraycopy, чтобы скопировать всё из result в tmp
tmp[tmp.length - 1] = product;
result = tmp;
}
}
return result;
}
public boolean matches(Product product, String search) {
// ваш код
}
}Требования к проекту:
- Создайте ветку (не делайте ДЗ в
master!) - Подключите плагин Surefire так, чтобы сборка падала в случае отсутсвия тестов
- Подключите плагин JaCoCo в режиме генерации отчётов (обрушать сборку по покрытию не нужно)
- Реализуйте нужные классы и методы
- Напишите автотесты на метод поиска (только на метод поиска в менеджере), добившись 100% покрытия по branch'ам* (вспомните, что мы говорили про тестирование методов, возвращающих набор значений)
- Подключите CI на базе Github Actions и выложите всё на Github
Примечание*: использовать Mockito или нет, мы оставляем на ваше усмотрение.
Итого: у вас должен быть репозиторий на GitHub, в котором расположен ваш Java-код в ветке (в master должен быть только pom.xml).
Достаточно часто объекты, моделирующие предметную область, называют моделями. Достаточно часто модели делают "глупыми", т.е. не содержащими никакой логики.
Но есть и другой подход, который позволяет делать "умные" или "богатые" модели (Rich Model), которые могут уже содержать определённую логику.
Что нужно сделать:
- Создайте новую ветку на базе ветки, в которой вы решали первую задачу
- Реализуйте в классе
Productметодpublic boolean matches(String search), который определяет, подходит ли продукт поисковому запросу исходя из названия - Переопределите этот метод в дочерних классах, чтобы они сначала вызывали родительский метод и только если родительский метод вернул
false, тогда проводили доп.проверки (Book- по автору,Smartphone- по производителю). - Уберите из менеджера все
instanceofи методmatches, т.к. теперь у вас "умные" модели и благодаря переопределению методов вам этот код больше не нужен - Зато теперь вам нужны unit-тесты на методы ваших умных моделей (напишите их)
- Удостоверьтесь, что ранее написанные тесты на менеджера (из решения задачи 1) проходят
Итого: у вас должен быть репозиторий на GitHub, в котором расположен ваш Java-код в двух ветках (в master должен быть только pom.xml).
Подсказка №1
public class ProductManager {
// добавьте необходимые поля, конструкторы и методы
public Product[] searcyBy(String text) {
Product[] result = new Product[0];
for (Product product: repository.findAll()) {
if (product.matches(text)) {
Product[] tmp = new Product[result.length + 1];
// используйте System.arraycopy, чтобы скопировать всё из result в tmp
tmp[tmp.length - 1] = product;
result = tmp;
}
}
return result;
}
}Подсказка №2 (про оператор ||)
У нас есть замечательный логический оператор ||, который работает следующим образом: вычисляет правую часть выражения только в случае, если левая равна false
public class Book {
// ваши поля, конструкторы, методы
public boolean matches(String search) {
return super.matches(search) || ... ваше выражение ...;
}
}Никто не говорит, что этот вариант лучше вот этого (наоборт, этот легче тестировать и отлаживать):
public class Book {
// ваши поля, конструкторы, методы
public boolean matches(String search) {
if (super.matches(search)) {
return true;
}
return ... ваше выражение ...;
}
}Но вы должны знать оба варианта.