Подтвердить что ты не робот

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

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

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

Неизменяемые объекты также рекомендуются в Пункт 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;
    }
}

Или ближе к struct в 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 становится более популярным с течением времени?

4b9b3361

Ответ 1

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

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

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

  • у вас есть небольшое количество простых свойств
  • вам не нужно взаимодействовать с средами, предполагающими соглашения JavaBean.
  • Легко (или, по крайней мере, возможно) копировать состояние при клонировании вашего объекта
  • вы вообще не планируете клонирование объекта
  • вы уверены, что вам никогда не придется изменять способ доступа к свойствам, как указано выше.
  • Вы не возражаете слушать, как нытье (или насмешка) о том, как ваш код недостаточно "объектно-ориентирован"

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

Подводя итог другим ответам, я думаю, что:

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

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

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

Ответ 5

Из Java 7 вы можете иметь неизменяемый beans, лучший из обоих миров. Используйте аннотацию @ConstructorProperties на вашем конструкторе.

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

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

    public String getName() {
        return name;
    }

    public Place getBirthPlace() {
        return birthPlace;
    }
}

Ответ 6

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

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

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

ИЗМЕНИТЬ. Комментарии дают мне немного разъяснить мой ответ.

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

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