10 KiB
Техническое задание: поиск студентов с использованием паттерна Компоновщик
Задача
Реализовать механизм поиска студентов по диапазону значений с использованием паттерна Компоновщик.
Должны поддерживаться следующие критерии поиска:
- диапазон
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() должен:
- Последовательно проверить студентов исходной коллекции.
- Передать каждого студента в:
criteria.matches(student)
- Добавить подходящих студентов в новую
MyList<Student>. - Вернуть новую коллекцию.
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);
Общие требования
StudentSearchServiceдолжен работать только черезStudentSearchCriteria.StudentSearchServiceне должен знать о конкретных критериях.CompositeStudentSearchCriteriaдолжен реализовывать тот же интерфейсStudentSearchCriteria.- Должна поддерживаться вложенность компоновщиков.
Например:
Composite
├── GroupNumberRangeCriteria
└── Composite
├── AverageGradeRangeCriteria
└── RecordBookNumberRangeCriteria
- Исходную
MyList<Student>не изменять. - Результат возвращать в виде новой
MyList<Student>. - Порядок найденных студентов должен сохраняться.
- Стандартные
List,ArrayList,LinkedListне использовать. - Готовые методы поиска не использовать.
- При отсутствии совпадений возвращать пустую
MyList<Student>. - Для диапазонов
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