Слишком много шаблонных, как я могу уменьшить мои POJO строители?
у меня несколько разных POJO-объекты чтобы использовать шаблона, но после добавления построителя для каждого из них и генерации Object.toString
, Object.hashCode
и Object.equals
, мои классы в конечном итоге составляют около 100 строк кода. Там должен быть лучший способ справиться с этим. Я думаю, что наличие какого-то рефлексивного строителя очень помогло бы, но я не уверен, что это будет хорошей практикой, и я также не уверен, как именно я это сделаю. Другими словами, есть ли способ реализовать такой конструктор?
простой POJO:
public class Foo {
public int id;
public String title;
public boolean change;
...
}
затем какой-то отражающий строитель:
Foo = ReflectiveBuilder.from(Foo.class).id(1).title("title").change(false).build();
4 ответов
короткий ответ:нет. То, о чем вы просите, невозможно. Отражение смотрит на код во время выполнения и вызывает методы динамически, оно не может генерировать фактические методы.
то, что вы могли бы сделать, было бы:
Foo foo = ReflectiveBuilder.from(Foo.class).
set("id", 1).
set("title", "title").
build();
это три огромные проблемы:
- поля
String
s - опечатка вызывает ошибку времени выполнения, а не время компиляции, - значения
Object
s-неправильный тип вызывает ошибку времени выполнения, а не компиляции, и - это было бы намного медленнее, чем альтернатива, поскольку отражение очень медленное.
таким образом, решение на основе отражения, хотя это возможно (см. Apache Commons BeanUtils BeanMap
) совсем не практично.
длинный ответ, если вы готовы разрешить некоторую магию времени компиляции, вы можете использовать Проект Lombok. Идея Lombok заключается в создании шаблонного кода из аннотации с помощью системы Java препроцессора аннотации.
действительно волшебная вещь заключается в том, что все IDEs, ну, по крайней мере, big 3, понимают предварительную обработку аннотаций и завершение кода все равно будут работать правильно, хотя код не действительно.
в случае POJO
С Builder
можно использовать @Data
и @Builder
@Data
@Builder
public class Foo {
public int id;
public String title;
public boolean change;
...
}
на @Data
аннотации создать:
- обязательный конструктор аргументов (который принимает все
final
поля), -
equals
иhashCode
методы, использующие все поля (можно настроить с помощью@EqualsAndHashCode
аннотация) - a
toString
метод на всех полях (можно настроить с помощью@ToString
аннотации и -
public
геттеры и сеттеры для всех полей (можно настроить с помощью@Getter
/@Setter
заметки на полях).
на @Builder
аннотация создаст внутренний класс под названием Builder
который может быть создан с помощью Foo.builder()
.
убедитесь, что вы настроить equals
, hashCode
и toString
методы, как если бы у вас было два класса с Ломбоком, которые имеют ссылки друг на друга, то вы получите бесконечный цикл в случае по умолчанию, поскольку оба класса включают друг друга в эти методы.
существует также новый конфигурация системы что позволяет использовать, например, свободно сеттеры, так что вы можете больше меньше покончить со строителем, если ваш POJO является изменчивым:
new Foo().setId(3).setTitle("title)...
для другого подхода вы можете посмотреть на аспектно-ориентированное программирование (AOP) и в AspectJ. AOP позволяет нарезать классы на "аспекты", а затем склеить их вместе, используя определенные правила с помощью предварительного компилятора. Например, вы можете реализовать именно то, что Lombok делает, используя пользовательские аннотации и аспект. Это довольно продвинутая тема, однако, и вполне может быть излишним.
может быть Проект Lombok (да, сайт уродливый) - это вариант для вас. Lombok вводит код в ваши классы на основе аннотаций.
С Ломбок вы используете @Data
аннотации к созданным геттеры, сеттеры, toString()
, hashCode()
и equals()
:
@Data
public class Foo {
public int id;
public String title;
public boolean change;
}
посмотрите на пример на @раздел документации по данным чтобы увидеть сгенерированный код.
Ломбок также предоставляет @Builder
который генерирует конструктор для ваш класс. Но имейте в виду, что это экспериментальная функция:
@Builder
public class Foo {
public int id;
public String title;
public boolean change;
}
теперь вы можете сделать:
Foo foo = Foo.builder()
.id(123)
.title("some title")
.change(true)
.build();
Я лично использую этой веб-сайт для создания всего кода шаблона для POJOs для меня. Все, что вам нужно сделать, это вставить JSON, который вы хотите обработать, и он будет генерировать классы для вас. Затем я просто использую Retrofit для выполнения запросов / кэширования / анализа информации. здесь является примером модернизации и POJOs в моей учетной записи Github. Надеюсь, это поможет!
Я создал небольшую библиотеку CakeMold для беглой инициализации POJOs. Он использует рефлексию, что, конечно, не быстро. Но может быть очень полезно, когда нужно писать тесты.
Person person = CakeMold.of(Person.class)
.set("firstName", "Bob")
.set("lastName", "SquarePants")
.set("email", "sponge.bob@bikinibottom.io")
.set("age", 22)
.cook();