Files

369 lines
11 KiB
Markdown
Raw Permalink Normal View History

2026-08-28 21:32:47 +04:00
# Техническое задание: `EvenOnlySortStrategy`
## Задача
Создать класс `EvenOnlySortStrategy`, реализующий дополнительное задание по сортировке элементов с чётным значением выбранного числового поля.
Класс должен использовать **паттерн Стратегия**: он не реализует собственный алгоритм сортировки, а делегирует сортировку переданной реализации `SortStrategy`.
## Контракт
Класс:
```java
public class EvenOnlySortStrategy<T> implements SortStrategy<T>
```
Должен содержать два конструктора:
```java
public EvenOnlySortStrategy()
```
```java
public EvenOnlySortStrategy(SortStrategy<T> sortStrategy)
```
Также реализовать метод:
```java
public void setSortStrategy(SortStrategy<T> sortStrategy)
```
и основной метод интерфейса `SortStrategy`:
```java
@Override
public void sort(
MyList<T> list,
Comparator<T> comparator
)
```
Для определения чётности числового поля использовать:
```java
ToIntFunction<T>
```
Поэтому рекомендуется также передавать функцию получения числового значения через конструктор или отдельный метод настройки.
Для `Student` в качестве функции использовать:
```java
Student::getRecordBookNumber
```
## Поведение при отсутствии стратегии
Если `sortStrategy` не задан:
```java
EvenOnlySortStrategy<Student> strategy =
new EvenOnlySortStrategy<>();
```
то вызов:
```java
strategy.sort(students, comparator);
```
должен завершаться контролируемой ошибкой.
Рекомендуется выбрасывать:
```java
IllegalStateException
```
с понятным сообщением о том, что стратегия сортировки не задана.
Не следует использовать `null` как признак успешного выполнения сортировки.
## Поведение `setSortStrategy`
Метод:
```java
setSortStrategy(SortStrategy<T> 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<T>` определить чётность каждого элемента.
3. Запомнить позиции элементов с чётным значением.
4. Сформировать отдельный `MyList<T>` только из чётных элементов.
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<Student> strategy =
new EvenOnlySortStrategy<>(
new MergeSortStrategy<>(),
Student::getRecordBookNumber
);
```
А также после создания заменить стратегию:
```java
strategy.setSortStrategy(new AnotherSortStrategy<>());
```
После этого специальная сортировка должна использовать новую стратегию без изменения `EvenOnlySortStrategy`.
## Требования к `ToIntFunction`
Функция получения числового значения должна передаваться извне.
Для `Student`:
```java
Student::getRecordBookNumber
```
Стратегия не должна напрямую обращаться к:
```java
student.getRecordBookNumber()
```
или к другим полям `Student`.
Это позволяет использовать класс с другими типами объектов и другими числовыми полями.
## Требования к коллекциям
Работать необходимо с:
```java
MyList<T>
```
Использование `ArrayList`, `LinkedList` и других стандартных коллекций для хранения элементов запрещено.
Вспомогательная коллекция чётных элементов также должна быть `MyList<T>`.
## Тесты
### Переданная стратегия используется
Передать `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<T>
MyList<T>
Comparator<T>
ToIntFunction<T>
```
и **не должен содержать реализации конкретного алгоритма сортировки**.
## Git
Ветка:
```text
feature/even-only-sort-strategy
```