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


я реализовал несколько приложений Java сейчас, только настольные приложения до сих пор. Я предпочитаю использовать неизменяемые объекты для передачи данных в приложении вместо использования объектов с мутаторами (setters и геттеры), также называется 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 реализован как неизменяемые

6 75

6 ответов:

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

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

Предпочитают Неизменяемые POJOs, Когда

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

меня удивило, что слово Thread нигде не появлялся в этой дискуссии.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

из Java 7 Вы можете иметь неизменяемые бобы, лучшие из обоих миров. Используйте аннотацию @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;
    }
}

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

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

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

EDIT комментарии предлагают мне уточнить мой ответ a немного.

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

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