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

10 KiB
Raw Permalink Blame History

Техническое задание: поиск студентов с использованием паттерна Компоновщик

Задача

Реализовать механизм поиска студентов по диапазону значений с использованием паттерна Компоновщик.

Должны поддерживаться следующие критерии поиска:

  • диапазон groupNumber;
  • диапазон averageGrade;
  • диапазон recordBookNumber.

Критерии должны поддерживать объединение в составной критерий.

Режим объединения критериев — объединение (ИЛИ) или пересечение (И) — задаётся в конструкторе основного класса.


Названия классов и интерфейсов

StudentSearchCriteria

Интерфейс отдельного критерия поиска.

Контракт

boolean matches(Student student);

Метод возвращает true, если студент соответствует критерию.


GroupNumberRangeCriteria

Критерий поиска по диапазону groupNumber.

Конструктор

GroupNumberRangeCriteria(String min, String max);

Метод

boolean matches(Student student);

groupNumber имеет тип String, поэтому сравнение выполнять лексикографически.

Границы диапазона включаются.


AverageGradeRangeCriteria

Критерий поиска по диапазону averageGrade.

Конструктор

AverageGradeRangeCriteria(double min, double max);

Метод

boolean matches(Student student);

Студент соответствует критерию, если:

min <= averageGrade <= max

RecordBookNumberRangeCriteria

Критерий поиска по диапазону recordBookNumber.

Конструктор

RecordBookNumberRangeCriteria(int min, int max);

Метод

boolean matches(Student student);

Студент соответствует критерию, если:

min <= recordBookNumber <= max

CompositeStudentSearchCriteria

Компоновщик критериев поиска.

Класс реализует:

StudentSearchCriteria

и содержит другие реализации StudentSearchCriteria.

Методы

void add(StudentSearchCriteria criteria);
void remove(StudentSearchCriteria criteria);
boolean matches(Student student);

Логика

CompositeStudentSearchCriteria должен поддерживать два режима:

UNION       — объединение условий, ИЛИ
INTERSECTION — пересечение условий, И

Режим должен задаваться при создании компоновщика:

CompositeStudentSearchCriteria(
    SearchOperation operation
);

где SearchOperation — перечисление:

public enum SearchOperation {
    UNION,
    INTERSECTION
}

Для UNION студент подходит, если выполняется хотя бы один вложенный критерий.

Для INTERSECTION студент подходит, если выполняются все вложенные критерии.


StudentSearchService

Основной класс поиска.

Он должен принимать интерфейс StudentSearchCriteria, а не конкретную реализацию критерия.

Конструктор

StudentSearchService(StudentSearchCriteria criteria);

Метод

MyList<Student> find(MyList<Student> students);

Поведение

Метод find() должен:

  1. Последовательно проверить студентов исходной коллекции.
  2. Передать каждого студента в:
criteria.matches(student)
  1. Добавить подходящих студентов в новую MyList<Student>.
  2. Вернуть новую коллекцию.

StudentSearchService не должен содержать логику конкретных диапазонов или объединения критериев.

Обработка отсутствующего критерия

Если StudentSearchService создан без критерия:

new StudentSearchService(null);

необходимо выбросить:

IllegalArgumentException

Класс не должен выполнять поиск без заданного критерия.


Пример использования

Один критерий

StudentSearchCriteria criteria =
        new AverageGradeRangeCriteria(4.0, 5.0);

StudentSearchService service =
        new StudentSearchService(criteria);

MyList<Student> result =
        service.find(students);

Пересечение критериев

Например, студент должен одновременно:

  • находиться в группе от A10 до C30;
  • иметь средний балл от 4.0 до 5.0.
CompositeStudentSearchCriteria criteria =
        new CompositeStudentSearchCriteria(
                SearchOperation.INTERSECTION
        );

criteria.add(
        new GroupNumberRangeCriteria("A10", "C30")
);

criteria.add(
        new AverageGradeRangeCriteria(4.0, 5.0)
);

StudentSearchService service =
        new StudentSearchService(criteria);

Объединение критериев

Студент должен соответствовать хотя бы одному условию:

CompositeStudentSearchCriteria criteria =
        new CompositeStudentSearchCriteria(
                SearchOperation.UNION
        );

criteria.add(
        new AverageGradeRangeCriteria(4.5, 5.0)
);

criteria.add(
        new RecordBookNumberRangeCriteria(10000, 20000)
);

StudentSearchService service =
        new StudentSearchService(criteria);

Общие требования

  1. StudentSearchService должен работать только через StudentSearchCriteria.
  2. StudentSearchService не должен знать о конкретных критериях.
  3. CompositeStudentSearchCriteria должен реализовывать тот же интерфейс StudentSearchCriteria.
  4. Должна поддерживаться вложенность компоновщиков.

Например:

Composite
 ├── GroupNumberRangeCriteria
 └── Composite
      ├── AverageGradeRangeCriteria
      └── RecordBookNumberRangeCriteria
  1. Исходную MyList<Student> не изменять.
  2. Результат возвращать в виде новой MyList<Student>.
  3. Порядок найденных студентов должен сохраняться.
  4. Стандартные List, ArrayList, LinkedList не использовать.
  5. Готовые методы поиска не использовать.
  6. При отсутствии совпадений возвращать пустую MyList<Student>.
  7. Для диапазонов min > max выбрасывать IllegalArgumentException.

Примеры тестов

GroupNumberRangeCriteria

Проверить:

  • значение внутри диапазона;
  • значение равное нижней границе;
  • значение равное верхней границе;
  • значение вне диапазона.

AverageGradeRangeCriteria

Проверить:

3.9 → false
4.0 → true
4.5 → true
5.0 → true
5.1 → false

RecordBookNumberRangeCriteria

Проверить значения внутри и вне диапазона, включая обе границы.

Некорректный диапазон

Для каждого критерия проверить:

min > max

Ожидается:

IllegalArgumentException

INTERSECTION

Создать два критерия и проверить:

критерий A = true
критерий B = true
→ true
критерий A = true
критерий B = false
→ false

UNION

Проверить:

A = true
B = false
→ true
A = false
B = true
→ true
A = false
B = false
→ false

Компоновщик без критериев

Проверить поведение:

new CompositeStudentSearchCriteria(
    SearchOperation.INTERSECTION
);

и:

new CompositeStudentSearchCriteria(
    SearchOperation.UNION
);

Поведение должно быть явно определено и закреплено тестами.

Рекомендуется:

  • пустое INTERSECTION → true;
  • пустое UNION → false.

StudentSearchService

Проверить:

  • корректный поиск по одному критерию;
  • пустой результат;
  • пустую исходную коллекцию;
  • сохранение порядка;
  • неизменность исходной коллекции;
  • работу с CompositeStudentSearchCriteria.

Проверка вложенного Компоновщика

Создать компоновщик с вложенным компоновщиком и проверить корректность вычисления результата.

Проверка отсутствующего критерия

Создать:

new StudentSearchService(null);

Проверить IllegalArgumentException.

Результат

Реализовать:

StudentSearchCriteria.java
GroupNumberRangeCriteria.java
AverageGradeRangeCriteria.java
RecordBookNumberRangeCriteria.java
CompositeStudentSearchCriteria.java
SearchOperation.java
StudentSearchService.java

Git

Название ветки:

feature/composite-student-search