Skip to content

Latest commit

 

History

History
 
 

inheritance

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Домашнее задание к занятию «Наследование и расширяемость систем. Проблемы наследования»

В качестве результата пришлите ссылки на ваши GitHub-проекты в личном кабинете студента на сайте netology.ru.

Все задачи этого занятия можно делать в одном репозитории.

Важно: если у вас что-то не получилось, то оформляйте Issue по установленным правилам.

Вы можете делать все задачи этого занятия в одном репозитории (если делаете их в разных ветках).

Как сдавать задачи

  1. Ознакомьтесь с особенностями Lombok при использовании наследования
  2. Ознакомьтесь с доп.материалами о static и reflection
  3. Инициализируйте на своём компьютере пустой Git-репозиторий
  4. Добавьте в него готовый файл .gitignore
  5. Добавьте в этот же каталог необходимые файлы (pom.xml)
  6. Сделайте ветки для первой задачи (после того, как сделаете первую задачу, на её основе создайте ветку для второй задачи)
  7. Создайте публичный репозиторий на GitHub и свяжите свой локальный репозиторий с удалённым
  8. Сделайте пуш (удостоверьтесь, что ваш код и обе ветки появились на GitHub)
  9. Ссылку на ваш проект отправьте в личном кабинете на сайте netology.ru
  10. Задачи, отмеченные как необязательные, можно не сдавать, это не повлияет на получение зачета (в этом ДЗ все задачи являются обязательными)

Задача №1 - "Менеджер Товаров"

На основании проекта из лекции необходимо реализовать менеджер товаров, который умеет:

  1. Добавлять товары в репозиторий
  2. Искать товары (репозиторий должен отдать все товары, а менеджер уже потом по ним ищет*)

Примечание*: это не самый эффективный способ. Когда мы будем проходить базы данных, поговорим, что это лучше делать там (ещё лучше - воспользоваться специализированным решением).

Что нужно сделать:

  1. Разработайте базовый класс Product, содержащий id, название, стоимость
  2. Разработать два унаследованных от Product класса: Book (с полями название* и автор) и Smartphone (с полями название* и производитель)
  3. Разработайте репозиторий, позволяющий сохранять Product'ы, получать все сохранённые Product'ы и удалять по id
  4. Разработайте менеджера, который умеет добавлять 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) {
    // ваш код
  }
}

Требования к проекту:

  1. Создайте ветку (не делайте ДЗ в master!)
  2. Подключите плагин Surefire так, чтобы сборка падала в случае отсутсвия тестов
  3. Подключите плагин JaCoCo в режиме генерации отчётов (обрушать сборку по покрытию не нужно)
  4. Реализуйте нужные классы и методы
  5. Напишите автотесты на метод поиска (только на метод поиска в менеджере), добившись 100% покрытия по branch'ам* (вспомните, что мы говорили про тестирование методов, возвращающих набор значений)
  6. Подключите CI на базе Github Actions и выложите всё на Github

Примечание*: использовать Mockito или нет, мы оставляем на ваше усмотрение.

Итого: у вас должен быть репозиторий на GitHub, в котором расположен ваш Java-код в ветке (в master должен быть только pom.xml).

Задача №2 - "Менеджер Товаров" (Rich Model)

Легенда

Достаточно часто объекты, моделирующие предметную область, называют моделями. Достаточно часто модели делают "глупыми", т.е. не содержащими никакой логики.

Но есть и другой подход, который позволяет делать "умные" или "богатые" модели (Rich Model), которые могут уже содержать определённую логику.

Что нужно сделать:

  1. Создайте новую ветку на базе ветки, в которой вы решали первую задачу
  2. Реализуйте в классе Product метод public boolean matches(String search), который определяет, подходит ли продукт поисковому запросу исходя из названия
  3. Переопределите этот метод в дочерних классах, чтобы они сначала вызывали родительский метод и только если родительский метод вернул false, тогда проводили доп.проверки (Book - по автору, Smartphone - по производителю).
  4. Уберите из менеджера все instanceof и метод matches, т.к. теперь у вас "умные" модели и благодаря переопределению методов вам этот код больше не нужен
  5. Зато теперь вам нужны unit-тесты на методы ваших умных моделей (напишите их)
  6. Удостоверьтесь, что ранее написанные тесты на менеджера (из решения задачи 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 ... ваше выражение ...;
  }
}

Но вы должны знать оба варианта.