Spring MVC дублирование кода, как избавиться?
Я пишу Spring MVC приложение. На главной странице у меня есть блок для поиска, фильтрации и сортировки полученных даных. Метод контроллера который работает с этой страницей выглядит так:
@RequestMapping(method = RequestMethod.GET)
public String showAll(Model model,
@RequestParam(value = "address", required = false) String address,
@RequestParam(value = "roomsMin", required = false) Integer roomsMin,
@RequestParam(value = "roomsMax", required = false) Integer roomsMax,
@RequestParam(value = "areaMin", required = false) Double areaMin,
@RequestParam(value = "areaMax", required = false) Double areaMax,
@RequestParam(value = "floorMin", required = false) Integer floorMin,
@RequestParam(value = "floorMax", required = false) Integer floorMax,
@RequestParam(value = "totalFloorsMin", required = false) Integer totalFloorsMin,
@RequestParam(value = "totalFloorsMax", required = false) Integer totalFloorsMax,
@RequestParam(value = "priceMin", required = false) Integer priceMin,
@RequestParam(value = "priceMax", required = false) Integer priceMax,
@RequestParam(value = "balconyTrue", required = false) boolean balcony,
@RequestParam(value = "sort", required = false, defaultValue = "Created") String sort) {
List<Apartment> result = apartmentService.findAll().stream()
.filter(apartment -> address == null || apartment.getAddressFormat().contains(address))
.filter(apartment -> roomsMin == null || apartment.getNumberOfRooms() >= roomsMin)
.filter(apartment -> roomsMax == null || apartment.getNumberOfRooms() <= roomsMax)
.filter(apartment -> areaMin == null || apartment.getArea() >= areaMin)
.filter(apartment -> areaMax == null || apartment.getArea() <= areaMax)
.filter(apartment -> floorMin == null || apartment.getFloor() >= floorMin)
.filter(apartment -> floorMax == null || apartment.getFloor() <= floorMax)
.filter(apartment -> totalFloorsMin == null || apartment.getTotalFloors() >= totalFloorsMin)
.filter(apartment -> totalFloorsMax == null || apartment.getTotalFloors() <= totalFloorsMax)
.filter(apartment -> priceMin == null || apartment.getPrice() >= priceMin)
.filter(apartment -> priceMax == null || apartment.getPrice() <= priceMax)
.filter(apartment -> !balcony || apartment.getBalconyAvailability())
.sorted(((apartment1, apartment2) -> {
if(sort.equals("New ones first")) {
return apartment2.getCreated().compareTo(apartment1.getCreated());
} else if (sort.equals("Rooms")) {
return apartment1.getNumberOfRooms().compareTo(apartment2.getNumberOfRooms());
} else if (sort.equals("Area")) {
return apartment1.getArea().compareTo(apartment2.getArea());
} else if (sort.equals("Price")) {
return apartment1.getPrice().compareTo(apartment2.getPrice());
}
return apartment1.getCreated().compareTo(apartment2.getCreated());
}))
.collect(Collectors.toList());
model.addAttribute("allApartments", result);
model.addAttribute("currentUserName", SecurityUtil.getCurrentUserFirstNameAndLastName());
model.addAttribute("currentUser", SecurityUtil.getCurrentUser());
model.addAttribute("isFavorites", "No");
return "main";
}
Из-за того что полей много метод получается довольно массивный. Дело в том что у меня есть ещё две страницы похожие на главную которые используют тот же блок поиска, фильтрации и сортировки. Получается что такой большой блок кода повторяется в трёх методах, а отличие только в одной строчке .filter()....
Я могу написать специальный метод который будет делать эту работу и использовать его в трёх местах, но в таком случае я буду каждый раз дважды вызывать .steam() на одной и той же коллекции, первый раз что бы проделать общую работу, второй раз что бы вызвать один .filter() в котором заключается отличие.
Как решить эту задачу с точки зрения наилучших практик?