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