Почему я не должен использовать неизменяемые POJO вместо JavaBeans?

Я реализовал несколько приложений Java сейчас, пока только настольные приложения. Я предпочитаю использовать неизменяемые объекты для передачи данных в приложении вместо использования объектов с мутаторами (setters и getters ), также называемыми JavaBeans.

Но в мире Java это, кажется, очень более распространено использование JavaBeans, и я не могу понять, почему я должен использовать их вместо этого. Лично код выглядит лучше, если он работает только с неизменяемыми объектами, а не постоянно изменяет состояние.

Неизменяемые объекты также рекомендуются в Item 15: Минимизируйте изменчивость , Эффективная Java 2ed .

Если у меня есть объект Person , реализованный как JavaBean , он будет выглядеть следующим образом:

public class Person {
    private String name;
    private Place birthPlace;

    public Person() {}

    public setName(String name) {
        this.name = name;
    }

    public setBirthPlace(Place birthPlace) {
        this.birthPlace = birthPlace;
    }

    public String getName() {
        return name;
    }

    public Place getBirthPlace() {
        return birthPlace;
    }
}

И тот же Person , реализованный как неизменяемый объект :

public class Person {
    private final String name;
    private final Place birthPlace;

    public Person(String name, Place birthPlace) {
        this.name = name;
        this.birthPlace = birthPlace;
    }

    public String getName() {
        return name;
    }

    public Place getBirthPlace() {
        return birthPlace;
    }
}

Или ближе к структуре в C:

public class Person {
    public final String name;
    public final Place birthPlace;

    public Person(String name, Place birthPlace) {
        this.name = name;
        this.birthPlace = birthPlace;
    }
}

Я также мог бы иметь геттеры в неизменяемом объекте скрыть детали реализации. Но так как я использую его только как struct , я предпочитаю пропускать «получатели» и сохранять их простыми.

Просто я не понимаю, почему лучше использовать JavaBeans, или если я могу и стоит ли продолжать работать с моими неизменными POJO?

Многие из библиотек Java, похоже, лучше поддерживают JavaBeans, но, может быть, со временем популярность неизменных POJO становится все более популярной?

78
задан Jonas 18 August 2010 в 16:36
поделиться

5 ответов

Предпочитать JavaBeans Когда

  • вам нужно взаимодействовать со средами, которые их ожидают
  • , у вас есть много свойств, для которых было бы неудобно выполнять всю инициализацию при создании экземпляра
  • , у вас есть состояние, которое по какой-то причине дорого или невозможно скопировать, но требует изменения
  • вы думаете, что в какой-то момент вам, возможно, придется изменить способ доступа к свойствам (например, переход от сохраненных к вычисляемым значениям, авторизация доступа и т. д.)
  • вы хотите соответствовать стандартам кодирования, которые бездумно настаивают на том, что использование JavaBeans как-то более «объектно-ориентировано»

Предпочитают неизменяемые POJO. Когда

  • у вас есть небольшое количество простых свойств
  • , вам не нужно взаимодействовать с окружением предполагая соглашения JavaBean
  • , легко (или, по крайней мере, возможно) скопировать состояние при клонировании вашего объекта
  • , вы никогда не планируете клонировать объект вообще
  • вы почти уверены, что не используете 'никогда не нужно изменять способ доступа к свойствам, как указано выше
  • , вам не нужно' Не обращайте внимания на нытье (или насмешки) о том, что ваш код недостаточно «объектно-ориентирован»
76
ответ дан 24 November 2019 в 10:35
поделиться

Я был удивлен, что слово Thread не появилось нигде в этом обсуждении.

Одним из основных преимуществ неизменяемых классов является то, что они по своей природе более потокобезопасны из-за отсутствия изменяемого разделяемого состояния.

Это не только упрощает кодирование, но и дает два побочных эффекта в производительности:

  • Меньше необходимости в синхронизации.

  • Больше возможностей для использования конечных переменных, которые могут облегчить последующую оптимизацию компилятора.

Я действительно пытаюсь перейти к неизменяемым объектам, а не к классам стиля JavaBean. Вероятно, не следует использовать методы по умолчанию для раскрытия сущности объектов с помощью геттеров и сеттеров.

39
ответ дан 24 November 2019 в 10:35
поделиться

Ну, это зависит от того, что вы пытаетесь сделать. Если вы работаете с постоянным слоем и извлекаете какую-то строку из базы данных в POJO, и вы хотите изменить свойство и сохранить его обратно, использование стиля JavaBean будет лучше, особенно если у вас много свойств.

Учтите, что у вашего человека есть много полей, таких как имя, отчество, фамилия, дата рождения, члены семьи, образование, работа, зарплата и т. Д.

И этот Человек оказался женщиной, которая только что получила замужем и согласились на изменение фамилии, и вам необходимо обновить базу данных.

Если вы используете неизменяемый POJO, вы выбираете объект Person, представляющий ее, затем вы создаете новый объект Person, которому вы передаете все свойства, которые вы не изменили, как они есть, и новую фамилию, и сохрани это.

Если бы это был компонент Java, вы можете просто выполнить setLastName () и сохранить его.

Это «минимизируйте изменчивость», а не «никогда не используйте изменяемые объекты».Некоторые ситуации лучше работают с изменяемыми объектами, на самом деле ваша задача - решить, подойдет ли создание изменяемого объекта для вашей программы или нет. Вы не должны всегда говорить «необходимо использовать неизменяемые объекты», вместо этого посмотрите, сколько классов вы можете сделать неизменяемыми, прежде чем начнете навредить себе.

16
ответ дан 24 November 2019 в 10:35
поделиться

Обобщая другие ответы, я думаю, что:

  • Неизменяемость способствует правильности (структуры могут передаваться по ссылке, и вы знаете, что ничего не будет уничтожено неисправным / злонамеренным клиентом) и простота кода
  • Изменчивость способствует однородности : Spring и другие фреймворки создают объект без аргументов, задают свойства объекта и voi là . Также упростите интерфейсы, используя тот же класс для передачи данных и сохранения изменений (вам не нужны get (id): Client и save (MutableClient) , будучи MutableClient некоторым потомком Client .

Если бы существовала промежуточная точка (создание, установка свойств, создание неизменяемого), возможно, фреймворки поощряли бы более неизменяемый подход.

В любом случае я предлагаю думать о неизменяемых объектах как о «Java Beans только для чтения», подчеркивая, что если ты хороший мальчик и не трогай этот опасный метод setProperty, все будет хорошо.

7
ответ дан 24 November 2019 в 10:35
поделиться

Я не думаю, что неизменяемые объекты станут настолько популярными, если честно.

Я действительно вижу преимущества, но такие фреймворки, как Hibernate и Spring, в настоящее время очень популярны (и по уважительной причине), и они действительно лучше всего работают с bean-компонентами.

Я не думаю, что неизменяемость - это плохо, но она определенно ограничит ваши возможности интеграции с текущими фреймворками.

РЕДАКТИРОВАТЬ Комментарии побуждают меня немного уточнить свой ответ.

Безусловно, существуют проблемные области, в которых неизменяемость очень полезна и действительно используется. Но я думаю, что текущее значение по умолчанию кажется изменяемым, поскольку это то, что в основном ожидается, и неизменным только в том случае, если у этого есть явное преимущество.

И хотя действительно можно использовать конструкторы с аргументами в Spring, похоже, это задумано как способ использования унаследованного и / или стороннего кода с красивым совершенно новым кодом Spring. По крайней мере, это то, что я взял из документации.

1
ответ дан 24 November 2019 в 10:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: