2. Упростить вложенные лямбда-выражения
Условие задачи:
Дан код, который ищет пользователей с правом редактирования.
Необходимо:
разобраться, что делает метод
findEditors();улучшить читаемость кода;
уменьшить сложность вложенных лямбда-выражений.
Код:
public class AvoidComplexLambdas {
private final Set<User> users = new HashSet<>();
public Set<User> findEditors() {
return users.stream()
.filter(u -> u.getRoles().stream()
.anyMatch(r -> r.getPermissions().contains(Permission.EDIT)))
.collect(Collectors.toSet());
}
}
Спойлеры к решению
Подсказки
💡 Метод оставляет пользователей, у которых хотя бы одна роль содержит разрешение
💡 Основная проблема читаемости — вложенная логика внутри
💡 Её можно вынести в отдельный метод с говорящим названием.
💡 После этого в
EDIT.💡 Основная проблема читаемости — вложенная логика внутри
filter().💡 Её можно вынести в отдельный метод с говорящим названием.
💡 После этого в
filter() можно использовать ссылку на метод.Решение
Метод ищет пользователей, у которых есть хотя бы одна роль с разрешением Permission.EDIT.
Вложенную проверку лучше вынести в отдельный метод:
public class AvoidComplexLambdas {
private final Set<User> users = new HashSet<>();
public Set<User> findEditors() {
return users.stream()
.filter(this::hasEditPermission)
.collect(Collectors.toSet());
}
private boolean hasEditPermission(User user) {
return user.getRoles().stream()
.anyMatch(role ->
role.getPermissions().contains(Permission.EDIT));
}
}
Теперь основной метод читается практически как описание бизнес-логики:
.filter(this::hasEditPermission)
Отдельный метод:
private boolean hasEditPermission(User user)
скрывает детали обхода ролей и явно сообщает, что именно проверяется.
Такой рефакторинг:
уменьшает вложенность;
делает
findEditors()проще для чтения;позволяет отдельно тестировать проверку наличия разрешения;
упрощает изменение логики проверки в будущем.