Сейчас появляются новые модные языки использующие парадигму функционального программирования. Тем не менее, в обычной Java
можно использовать функции для описания поведения объектов. Причём делать это можно полностью в рамках синтаксиса Java.
Я опубликовал Java-библиотеку позволяющую связывать (binding) объекты через функции (см. https://code.google.com/p/tee-binding/ )

public class It‹E›
— основной класс, содержит ссылку на объект любого типа и обновляет все связи при изменении значений в одном из экземпляров. Пример
результат:
Класссы Number, Note, Toggle являются производными класса It для хранения значений конкретного типа (соответственно для Double, String и Boolean) и содержат методы задания связывания с использованием функций. Пример:
результат:
как видно, это функция конвертации температуры из шкалы Цельсия в шкалу Фаренгейта (F' = C' * 9 / 5 + 32). Из определения переменной
это вполне очевидно. Также можно отметить что связывание через функцию является двунаправленным.
Примечание: псевдооператоры функции вычисляются последовательно без учёта приориетета операций.
Для более сложных случаев можно использовать класс Fork. Он позволяет использовать в связывании условия, пример:
результат:
Запись условия вполне наглядна, в зависимости от значения переменной n, в переменную r заносится текст Frost, Cold, Warm или Hot.
К сожалению, связывание и функции нельзя использовать непосредственно. Рассмотрим модификации необходимые для применения связывания в Swing:
это класс расширяющий стандартный JLabel. Он позволяет обновлять связывать текст надписи с переменно имеющий тип Note.
Для редактируемых Swing-компонентов также придётся добавить ChangeListener. Пример определения поведения компонентов из формы на скриншоте:
— как видно, это занимает всего несколько строк и при редактировании любого значения в форме (или перемещения ползунка слайдера) остальные компоненты мгновенно обновляют своё состояние.
можно использовать функции для описания поведения объектов. Причём делать это можно полностью в рамках синтаксиса Java.
Я опубликовал Java-библиотеку позволяющую связывать (binding) объекты через функции (см. https://code.google.com/p/tee-binding/ )

Описание классов
public class It‹E›
— основной класс, содержит ссылку на объект любого типа и обновляет все связи при изменении значений в одном из экземпляров. Пример
It‹String› a1 = new It‹String›().value("A"); It‹String› a2 = new It‹String›().value("B"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.bind(a2); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.value("C"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a2.value("D"); System.out.println("a1: "+a1.value()+", a2: "+a2.value());
результат:
a1: A, a2: B a1: B, a2: B a1: C, a2: C a1: D, a2: D
Класссы Number, Note, Toggle являются производными класса It для хранения значений конкретного типа (соответственно для Double, String и Boolean) и содержат методы задания связывания с использованием функций. Пример:
Numeric c = new Numeric().value(0); Numeric f = c.multiply(9.0).divide(5.0).plus(32.0); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let f = 100 "); f.value(100); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let c = 100 "); c.value(100); System.out.println("f: " + f.value() + ", c: " + c.value());
результат:
f: 32.0, c: 0.0 /let f = 100 f: 100.0, c: 37.77777777777778 /let c = 100 f: 212.0, c: 100.0
как видно, это функция конвертации температуры из шкалы Цельсия в шкалу Фаренгейта (F' = C' * 9 / 5 + 32). Из определения переменной
Numeric f = c.multiply(9.0).divide(5.0).plus(32.0);это вполне очевидно. Также можно отметить что связывание через функцию является двунаправленным.
Примечание: псевдооператоры функции вычисляются последовательно без учёта приориетета операций.
Для более сложных случаев можно использовать класс Fork. Он позволяет использовать в связывании условия, пример:
System.out.println("/n = -10"); Numeric n = new Numeric().value(-10); Note r = new Note().bind(new Fork‹String›() .condition(new Toggle().less(n, -5)) .then("Frost") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +15)) .then("Cold") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +30)) .then("Warm") .otherwise("Hot") ))); System.out.println(r.value()); System.out.println("/let n = +10"); n.value(10); System.out.println(r.value()); System.out.println("/let n = +20"); n.value(20); System.out.println(r.value()); System.out.println("/let n = +40"); n.value(40); System.out.println(r.value());
результат:
/n = -10 Frost /let n = +10 Cold /let n = +20 Warm /let n = +40 Hot
Запись условия вполне наглядна, в зависимости от значения переменной n, в переменную r заносится текст Frost, Cold, Warm или Hot.
Применение библиотеки
К сожалению, связывание и функции нельзя использовать непосредственно. Рассмотрим модификации необходимые для применения связывания в Swing:
class BindableLabel extends JLabel { private Note bindableValue = new Note().value("").afterChange(new Task() { @Override public void job() { if (bindableValue != null) { setText(bindableValue.value()); } } }); public Note bindableValue() { return bindableValue; } public BindableLabel() { super(); } }
это класс расширяющий стандартный JLabel. Он позволяет обновлять связывать текст надписи с переменно имеющий тип Note.
Для редактируемых Swing-компонентов также придётся добавить ChangeListener. Пример определения поведения компонентов из формы на скриншоте:
void bindComponents() { Numeric celsius = new Numeric().value(0); Numeric fahrenheit = celsius.multiply(9.0).divide(5.0).plus(32.0); fahrenheitSlider.bindableValue().bind(fahrenheit); fahrenheitSpinner.bindableValue().bind(fahrenheit); celsiusSlider.bindableValue().bind(celsius); celsiusSpinner.bindableValue().bind(celsius);
— как видно, это занимает всего несколько строк и при редактировании любого значения в форме (или перемещения ползунка слайдера) остальные компоненты мгновенно обновляют своё состояние.