Функциональное программирование в Java — это подход в программировании особого вида, когда акцент программного кода сводится к использованию функций, а не инструкций. При таком подходе каждая отдельная функция используется как объект. А это значит, что функцию можно:
присвоить переменным;
передать в виде аргумента другой функции;
возвратить в качестве результата от другой функции;
и др.
«Но в Java нет функций», — скажете вы и окажетесь правы. Действительно, в Java присутствуют только классы, объекты классов и методы. Однако также присутствуют анонимные классы, то есть классы, у которых не обозначено имя. Их можно объявить в любом методе и интерфейсе. Если их интерфейс с анонимным классом объявить в каком-либо методе, тогда с подобным интерфейсом можно делать то же самое, что и с обычной функцией в функциональных языках. Благодаря такому свойству анонимных интерфейсов в Java возможно реализовать функциональное программирование.
Функциональное программирование в Java
Как функциональное программирования в Java выглядит на деле. Для начала давайте создадим вот такой интерфейс:
public finish interface MyFunction
{
R apply(P form);
}
Потом возьмем и объявим анонимную реализацию выше описанного интерфейса. Например так:
public static void main() {
// Объявим "анонимную функцию", присвоив ее значение переменной intAndString.
MyFunction intAndString = new MyFunction() {
@Override public MyString apply(Integer from) {
return from.AndString();
}
};
intAndString.apply(8000); // Происходит вызов нашей «анонимной функции», где в ответ получим строку "8000".
}
Чуть выше мы показали, как реализовывается «анонимная функция». Если рассматривать ее с позиции функционального программирования, тогда она ничем не отличается от обычной функции функциональных языков программирования. То есть с ней можно делать все, что обычно делают программисты с функциями. Таким образом Java «превращается» из объектно-ориентированного языка в функциональный язык программирования.
Функциональное программирование в Java: принципы
Хочется еще раз закрепить,что Java не является функциональным языком программирования, а обладает функциональными возможностями. По теме функционального программирования все языки делятся на 3 большие группы:
языки, которые специально спроектированы для реализации функциональной парадигмы, например: Haskell, Erlang, F# и др.;
языки, которые поддерживают возможности объектно-ориентированного и функционального программирования, например: Java, JavaScript, Python, PHP, C++ и др.;
языки, которые не поддерживают реализацию функционального программирования.
Функциональное программирование в Java реализуется по следующим принципам:
Переменные и функции. Это важнейшие составляющие функциональной парадигмы. С переменными в Java все в порядке, а вот с функциями нужно повозиться и реализовывать их через «анонимные» интерфейсы и методы.
Чистые функции. Такие функции не создают проблемных эффектов и при идентичном входящем значении всегда выдают одинаковый вывод. Благодаря «чистым» функциям снижается риск возникновения ошибок в программе.
Неизменяемые данные и состояния. После их определения данные или состоянияне могут видоизменяться. Благодаря этому свойству сохраняется постоянство рабочей среды для выводящих значений функции. При соблюдении этого принципа каждая функция воспроизводит один и тот же результат и не имеет зависимости от состояния программного обеспечения. Также такой принцип исключает применение функций с общим состоянием. Это когда в одно состояние программы упирается несколько функций.
Рекурсия. Это способ осуществлять перебор информации в функциональном программировании без использования цикла «if...else».
Первоклассность функций. Этот принцип позволяет применять функцию как обычное значение. Например, можно заполнить функциями массив или сохранить их в переменной.
Высший порядок функции. Этот принцип позволяет одной функции использовать другую функцию в качестве своего аргумента или возвращать ее в качестве исходящего значения.
Композиция функций. Этот принцип подразумевает построение структуры из функций, где результат выполнения одной функции будет передаваться в другую функцию, и так дальше по цепочке. Таким образом, при помощи вызова одной функции можно спровоцировать исполнение целой цепочки функций.
Преимущество функционального программирования в Java
Java поддерживает объектно-ориентированное и функциональное программирование. Поэтому можно рассмотреть, какими преимуществами функциональное программирование Java имеет перед его ОО-подходом. Например:
более легкая отладка за счет использования «чистых» функций и неизменных данных;
отложенное вычисление происходит за счет того, что функциональная программа вычисляется только при надобности;
модульность достигается за счет того, что «чистые» функции можно использовать в разных областях одного кода;
улучшенная читабельность достигается за счет того, что поведение каждой отдельной функции предсказуемо и неизменно;
облегченное параллельное программирование;
и др.
Заключение
Функциональное программирование в Java не является основной парадигмой, однако тоже довольно просто реализуется. Обычно функциональное программирование имеет смысл применять тогда, когда программные решения легко выражаются при помощи функций и не имеют тесной связи с реальным миром. ООП чаще всего реализуется, когда программа моделируется с использованием объектов из реальной жизни. Подробнее на разнице между ФП и ООП мы остановимся в следующих статьях.
JavaScript