11 KiB
Техническое задание: EvenOnlySortStrategy
Задача
Создать класс EvenOnlySortStrategy, реализующий дополнительное задание по сортировке элементов с чётным значением выбранного числового поля.
Класс должен использовать паттерн Стратегия: он не реализует собственный алгоритм сортировки, а делегирует сортировку переданной реализации SortStrategy.
Контракт
Класс:
public class EvenOnlySortStrategy<T> implements SortStrategy<T>
Должен содержать два конструктора:
public EvenOnlySortStrategy()
public EvenOnlySortStrategy(SortStrategy<T> sortStrategy)
Также реализовать метод:
public void setSortStrategy(SortStrategy<T> sortStrategy)
и основной метод интерфейса SortStrategy:
@Override
public void sort(
MyList<T> list,
Comparator<T> comparator
)
Для определения чётности числового поля использовать:
ToIntFunction<T>
Поэтому рекомендуется также передавать функцию получения числового значения через конструктор или отдельный метод настройки.
Для Student в качестве функции использовать:
Student::getRecordBookNumber
Поведение при отсутствии стратегии
Если sortStrategy не задан:
EvenOnlySortStrategy<Student> strategy =
new EvenOnlySortStrategy<>();
то вызов:
strategy.sort(students, comparator);
должен завершаться контролируемой ошибкой.
Рекомендуется выбрасывать:
IllegalStateException
с понятным сообщением о том, что стратегия сортировки не задана.
Не следует использовать null как признак успешного выполнения сортировки.
Поведение setSortStrategy
Метод:
setSortStrategy(SortStrategy<T> sortStrategy)
заменяет текущую стратегию.
После вызова метода последующая сортировка должна выполняться именно переданной стратегией.
Передача null должна приводить к контролируемой ошибке, например:
IllegalArgumentException
Основная бизнес-логика
EvenOnlySortStrategy не должен содержать код какого-либо алгоритма сортировки.
Запрещено реализовывать внутри класса:
- Merge Sort;
- Bubble Sort;
- Selection Sort;
- другие алгоритмы сортировки;
- вызовы стандартных методов сортировки Java.
Класс отвечает только за:
- определение элементов, участвующих в специальной сортировке;
- сохранение исходных позиций нечётных элементов;
- передачу подходящих элементов переданной
SortStrategy; - восстановление результата на исходные позиции;
- делегирование самого алгоритма сортировки.
Таким образом:
EvenOnlySortStrategy
│
├── определяет, какие элементы сортировать
│
├── передаёт сортируемые элементы
│ ↓
│ SortStrategy
│ ↓
│ MergeSortStrategy
│ QuickSortStrategy
│ ...
│
└── возвращает результат на исходные позиции
Один EvenOnlySortStrategy должен работать с любой реализацией SortStrategy.
Рекомендуемый алгоритм
Рекомендуется использовать следующий подход.
Исходная коллекция:
[7, 8, 3, 2, 5, 4]
При выборе recordBookNumber:
нечётные: 7, 3, 5
чётные: 8, 2, 4
- Пройти исходный
MyList. - С помощью
ToIntFunction<T>определить чётность каждого элемента. - Запомнить позиции элементов с чётным значением.
- Сформировать отдельный
MyList<T>только из чётных элементов. - Передать эту коллекцию в
sortStrategy.sort(...). - Полученные отсортированные элементы последовательно вернуть на сохранённые позиции.
- Элементы с нечётными значениями не изменять.
Например, переданная стратегия MergeSortStrategy сортирует:
[8, 2, 4]
в:
[2, 4, 8]
После возвращения элементов на исходные позиции:
[7, 2, 3, 4, 5, 8]
При этом EvenOnlySortStrategy не знает, каким способом были отсортированы 8, 2, 4.
Работа с любой SortStrategy
Должно быть возможно использовать:
EvenOnlySortStrategy<Student> strategy =
new EvenOnlySortStrategy<>(
new MergeSortStrategy<>(),
Student::getRecordBookNumber
);
А также после создания заменить стратегию:
strategy.setSortStrategy(new AnotherSortStrategy<>());
После этого специальная сортировка должна использовать новую стратегию без изменения EvenOnlySortStrategy.
Требования к ToIntFunction
Функция получения числового значения должна передаваться извне.
Для Student:
Student::getRecordBookNumber
Стратегия не должна напрямую обращаться к:
student.getRecordBookNumber()
или к другим полям Student.
Это позволяет использовать класс с другими типами объектов и другими числовыми полями.
Требования к коллекциям
Работать необходимо с:
MyList<T>
Использование ArrayList, LinkedList и других стандартных коллекций для хранения элементов запрещено.
Вспомогательная коллекция чётных элементов также должна быть MyList<T>.
Тесты
Переданная стратегия используется
Передать MergeSortStrategy.
Проверить, что сортировка чётных элементов выполняется переданной стратегией.
Замена стратегии
- Создать
EvenOnlySortStrategyс одной реализациейSortStrategy. - Выполнить сортировку.
- Вызвать
setSortStrategy(...). - Выполнить сортировку повторно.
- Проверить, что используется новая стратегия.
Конструктор без стратегии
Создать:
new EvenOnlySortStrategy<>();
Вызвать sort().
Проверить выброс IllegalStateException.
Конструктор со стратегией
Создать объект с MergeSortStrategy.
Проверить успешное выполнение сортировки.
Передача null в setSortStrategy
Проверить выброс IllegalArgumentException.
Все элементы нечётные
[7, 3, 5, 1]
Результат должен полностью совпадать с исходной коллекцией.
Все элементы чётные
[8, 2, 6, 4]
Ожидаемый результат:
[2, 4, 6, 8]
Смешанные значения
[7, 8, 3, 2, 5, 4]
Ожидаемый результат:
[7, 2, 3, 4, 5, 8]
Повторяющиеся значения
Проверить корректность сортировки при наличии одинаковых чётных значений.
Один элемент
Проверить отдельно чётный и нечётный элемент.
Пустая коллекция
Сортировка не должна приводить к ошибке.
Проверка сохранения нечётных элементов
Проверить не только значения, но и то, что объекты с нечётным recordBookNumber остались на тех же индексах.
Проверка разных реализаций
Использовать EvenOnlySortStrategy с каждой доступной реализацией SortStrategy.
Проверить, что результат специальной сортировки соответствует контракту независимо от конкретного алгоритма.
Проверка делегирования
Создать тестовую реализацию SortStrategy, которая фиксирует факт вызова sort().
Передать её в EvenOnlySortStrategy.
Проверить, что:
sort()был вызван;- в стратегию передана коллекция только с чётными элементами;
- сама
EvenOnlySortStrategyне выполняет сортировку самостоятельно.
Результат
Реализовать:
EvenOnlySortStrategy.java
Класс должен зависеть от абстракции:
SortStrategy<T>
MyList<T>
Comparator<T>
ToIntFunction<T>
и не должен содержать реализации конкретного алгоритма сортировки.
Git
Ветка:
feature/even-only-sort-strategy