Files
aston-team-project/docs/tasks/EvenOnlySortStrategy.md

369 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Техническое задание: `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
```