Fluent API — это стиль проектирования API, в котором методы возвращают объект, к которому они принадлежат, позволяя вызывать методы цепочкой (chaining).
Основные концепции
Method Chaining. Fluent API позволяет вызывать методы один за другим, что уменьшает количество промежуточных переменных и улучшает читаемость.
Самоописывающийся код. Использование цепочки методов делает код более понятным и логичным, приближая его к естественному языку.
Где встречается?
Фреймворки с реактивным подходом.
Java Stream
Библиотеки для работы с базами данных. Такие фреймворки, как JPA или Hibernate, используют Fluent API для создания запросов. Например, запросы могут выглядеть так
Настройка объектов. Fluent API часто используется в Builder Pattern, где объект строится поэтапно через цепочку методов.
Конфигурация. Например Spring Security, Kafka Streams
Фреймворки для тестирования. Например, в JUnit или AssertJ можно строить цепочки утверждений:
Fluent API часто используется для построения специфических языков (DSL), которые имитируют человеческий язык и делают код максимально самоописательным.
Пример императивного кода
И аналогичный в стиле Fluent API
Приемы и подходы
Method chaining
Method chaining — это техника, при которой методы возвращают текущий объект (обычно через this), позволяя вызывать несколько методов последовательно в одной строке.
Смена контекста
С помощью method chaining
Представим, что мы настраиваем серверное приложение с несколькими аспектами: базовая настройка, настройка безопасности, логирования и т.д. Здесь каждый вызов метода переключает нас на новый “контекст”, где мы продолжаем настраивать приложение, но в рамках другой области (например, с безопасности переключаемся на логирование).
С помощью лямбда-выражений
Step building
Позволяет организовать процесс создания объектов или выполнения операций через строго упорядоченные шаги. Хотя этот подход часто используется в Builder Pattern, он применим и в других контекстах, например, при вызове API, конфигурации сложных процессов, построении запросов и даже в рабочих процессах (workflow).
Основные концепции
Упорядоченные шаги. Процесс выполнения операции или создания объекта разделен на несколько этапов (шагов), которые должны выполняться в определённой последовательности. Каждый шаг может представлять собой настройку, изменение состояния или выполнение отдельной операции.
Контроль обязательных шагов. Пошаговая сборка гарантирует, что определенные важные шаги не будут пропущены. Это особенно полезно для процессов, где важно соблюдение последовательности действий или конфигурации обязательных параметров.
Примеры применения пошаговой сборки
Построение SQL-запросов
Самообобщение
Когда мы используем наследование для создания подклассов, возникает проблема, что методы Fluent API могут возвращать не подкласс, а базовый класс, разрывая цепочку вызовов. Самообобщение решает эту проблему, позволяя методам возвращать правильный тип подкласса.
Пример проблемы без самообобщения. Допустим, у нас есть базовый класс с цепочкой методов, и мы хотим унаследовать этот класс.
В этом примере setName() возвращает тип BaseBuilder, поэтому попытка вызвать setFeature() на результат этого вызова приведет к ошибке. Метод setFeature() будет недоступен.
Решение с использованием самообобщения (Self-type Generics). Мы можем решить эту проблему, используя самообобщение с помощью обобщений (generics). Это позволит методам возвращать самый специфичный тип.