Comments 13
Одна из задач действительно, как уже сказали, байндинг свойств бизнес объектов к интерфейсу. Другая задача может быть, например JPA EntityGraph, где указывается перечень свойств сущности, которые нужно достать из таблицы. И вообще везде, где требуется указание свойств объекта, вместо строки использовать статическую ссылку.
Как относитесь к использованию публичных полей вместо свойств? Коллеги меня убеждали, что это последний писк джава-моды, и геттеры-сеттеры уже никто не генерит, даже ломбоком.
Если структура immutable, поля public final, а ее использование промежуточное, например как результат функции, то вполне нормально. Для DTO тоже потянет (полагаю, что это основной кейс ваших коллег вкупе с каким-нибудь Spring Boot). Для mutable-структуры, хранящей бизнес данные необходимы геттеры-сеттеры, хотя бы потому что много фреймворков не работают с публичными полями.
К кодогенерации типа Immutables.org, JodaBean, AutoBean, QueryDSL etc. не пользуюсь: она хоть и типобезопасная, но затрудняет анализ и рефакторинг кода. Исплючение — ломбок, у него есть хороший плагин для IDEA.
По-моему, очень странное мнение у Ваших коллег.
На то несколько причин:
- В случае какого-либо изменения поведения, будь то pre-conditions или смена метода хранения этих данных, вам придётся обновлять код везде, где присутствует прямой доступ, зачастую дублируя логику (e.g перед каждым
foo.bar = baz;
какой-нибудьif (baz != null && foo.qux/* аналогично bad practice */).willNotBreakWith(baz))
). - Во-вторых, таким образом вы привязываетесь к конкретным классам, что усложняет значительно юнит-тестирование, потому что вы не можете даже задать логику работы с объектом через интерфейс.
- При этом, любой рефакторинг класса, имеющего эти поля, может повлечь ломание всего с ним связанного (и даже если в пределах проекта с этим может справиться IDE, то внешние пользователи Вашего API сломаются).
Возможно, конечно, они говорили о свойствах объектов, вроде того, как Kotlin даёт доступ к ним через foo.bar
, а не foo.bar()
, однако они, в свою очередь, также реализованы через (синтексические) аксессоры.
PS Понятное дело, что статичные, финальные, иммутабельные константы — это отдельная тема, но они и не имеют никакого отношения к свойствам объектов
Чесно говоря, не знал о линзах. Насколько я понял, речь о функциональной композиции для манипуляции с иерархическими immutable-структурами. Насчет практического использования не знаю — тут все-равно требуется сторонний кодогенератор типа Immutables, который бы сгенерил withXXX(), плюс генерация самих линз или их задание более удобоваримым способом (как например BeanRef). Как идея интересна. Возможно в BeanRef стоит добавить метод with() для работы с немутабельными объектами, который автоматически реализует "copy-and-set", и транзитивно применяет операцию по всей ветке.
Да, именно так.
Насколько я понимаю, для Java 8 вполне возможно создание линз примерно таким же способом, какой вы используете тут (в сущности, для лямбд и методов несмотря на erasure можно определить сигнатуру, поэтому все со времен Guava TypeToken примерно одинаковыми методами для этого и пользуются).
Вообще предложенная тут идея на первый взгляд очень к линзам близка.
Используем статические ссылки на свойства объектов при помощи лямбд