feat: implement composite pattern for student search

This commit is contained in:
Дюрягин Данил
2026-08-29 16:16:17 +03:00
parent 2e44ba8fd5
commit 0d1f0cbfc4
7 changed files with 163 additions and 0 deletions
@@ -0,0 +1,22 @@
package ru.project.search;
import ru.project.student.Student;
public class AverageGradeRangeCriteria implements StudentSearchCriteria {
private final double min;
private final double max;
public AverageGradeRangeCriteria(double min, double max) {
if (min > max) {
throw new IllegalArgumentException("Min grade must be <= max grade");
}
this.min = min;
this.max = max;
}
@Override
public boolean matches(Student student) {
double grade = student.getAverageGrade();
return grade >= min && grade <= max;
}
}
@@ -0,0 +1,51 @@
package ru.project.search;
import ru.project.student.Student;
import java.util.ArrayList;
import java.util.List;
public class CompositeStudentSearchCriteria implements StudentSearchCriteria {
private final SearchOperation operation;
private final List<StudentSearchCriteria> criteriaList = new ArrayList<>();
public CompositeStudentSearchCriteria(SearchOperation operation) {
if (operation == null) {
throw new IllegalArgumentException("Operation must not be null");
}
this.operation = operation;
}
public void add(StudentSearchCriteria criteria) {
if (criteria == null) {
throw new IllegalArgumentException("Criteria must not be null");
}
criteriaList.add(criteria);
}
public void remove(StudentSearchCriteria criteria) {
criteriaList.remove(criteria);
}
@Override
public boolean matches(Student student) {
if (criteriaList.isEmpty()) {
return operation == SearchOperation.INTERSECTION;
}
if (operation == SearchOperation.UNION) {
for (StudentSearchCriteria c : criteriaList) {
if (c.matches(student)) {
return true;
}
}
return false;
} else {
for (StudentSearchCriteria c : criteriaList) {
if (!c.matches(student)) {
return false;
}
}
return true;
}
}
}
@@ -0,0 +1,25 @@
package ru.project.search;
import ru.project.student.Student;
public class GroupNumberRangeCriteria implements StudentSearchCriteria {
private final String min;
private final String max;
public GroupNumberRangeCriteria(String min, String max) {
if (min == null || max == null) {
throw new IllegalArgumentException("Min and max must not be null");
}
if (min.compareTo(max) > 0) {
throw new IllegalArgumentException("Min group must be <= max group");
}
this.min = min;
this.max = max;
}
@Override
public boolean matches(Student student) {
String group = student.getGroupNumber();
return group.compareTo(min) >= 0 && group.compareTo(max) <= 0;
}
}
@@ -0,0 +1,22 @@
package ru.project.search;
import ru.project.student.Student;
public class RecordBookNumberRangeCriteria implements StudentSearchCriteria {
private final int min;
private final int max;
public RecordBookNumberRangeCriteria(int min, int max) {
if (min > max) {
throw new IllegalArgumentException("Min record number must be <= max");
}
this.min = min;
this.max = max;
}
@Override
public boolean matches(Student student) {
int number = student.getRecordBookNumber();
return number >= min && number <= max;
}
}
@@ -0,0 +1,6 @@
package ru.project.search;
public enum SearchOperation {
UNION,
INTERSECTION
}
@@ -0,0 +1,7 @@
package ru.project.search;
import ru.project.student.Student;
public interface StudentSearchCriteria {
boolean matches(Student student);
}
@@ -0,0 +1,30 @@
package ru.project.search;
import ru.project.list.MyList;
import ru.project.list.MyLinkedList;
import ru.project.student.Student;
public class StudentSearchService {
private final StudentSearchCriteria criteria;
public StudentSearchService(StudentSearchCriteria criteria) {
if (criteria == null) {
throw new IllegalArgumentException("Criteria must not be null");
}
this.criteria = criteria;
}
public MyList<Student> find(MyList<Student> students) {
if (students == null) {
return new MyLinkedList<>();
}
MyList<Student> result = new MyLinkedList<>();
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
if (criteria.matches(s)) {
result.add(s);
}
}
return result;
}
}