Бобы Java, поскольку классы хранения данных плохо разрабатывают?

Обычно JavaPractices.com является хорошим сайтом с хорошей идеей, но этот беспокоит меня: JavaBeans плохи.

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

Теперь я могу согласиться с последним, но в моих глазах JavaBeans в списке имеет намного больше смысла, чем вложенные Карты. Статья утверждает, что платформы отображения базы данных должны вызвать конструкторов, не набор* методы, и объект должен быть неизменным. В моем уме однако, называя набор* методы при попытке создать объект легче читать, чем new MappedObject("column1", "column2", "yet another column", "this is stupid");

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

Так мой вопрос: использует JavaBeans для хранения данных плохая практика и должен избежаться, или действительно ли это совершенно безопасно?

11
задан Jim Ferrans 26 June 2010 в 05:41
поделиться

6 ответов

Похоже, вы неправильно читаете текст.

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

В тексте никогда не упоминаются вложенные карты в качестве альтернативы (yiack)

... следует вызывать конструкторы, а не установленные * методы, и объект должен быть неизменяемым

Это хорошая практика, особенно полезная при работе с потоками.

Но мы также не можем сказать, что использование сеттеров baaad , особенно когда один поток использует объект. Это совершенно безопасно.

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

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

Является ли использование JavaBeans для хранения данных плохой практикой, и ее следует избегать, или это совершенно безопасно?

Нет, это неплохая практика. Не является совершенно безопасным . Зависит от ситуации.

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

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

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

Чтобы убедиться, что объект неизменяем, вы должны объявить свои атрибуты как final.

class MyBean  {
    private final int i;
}

Если вы хотите присвоить MyBean.i разумное значение, вы должны указать его в конструкторе:

 public MyBean( int i ) {
     this.i = i;
 }

Поскольку переменная является final, вы не можете использовать установщик.Вы можете просто предоставить геттер.

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

Это не плохая практика или хорошая практика. Нам необходимо работать с одним потоком, даже в многопоточных средах, таких как сервлеты.

Если в будущем вам придется иметь дело с многопоточными приложениями, вы можете подумать об использовании неизменяемого JavaBean;)

Кстати, альтернатива для создания неизменяемых bean-компонентов и по-прежнему предоставляет кучу установщиков использует Builders например:

 Employee e = new EmployeeBuilder()
                  .setName("Oscar")
                  .setLastName("Reyes")
                  .setAge(0x1F)
                  .setEmployeeId("123forme")
                  .build(); 

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

Если вам нужно изменить одно значение, вы можете использовать метод класса:

 Employee e = Employee.withName( e, "Mr. Oscar");

Который берет существующий объект, копирует все значения и устанавливает новое ....

 public static EmployeeWithName( Employee e , String newName ){
      return new Employee( newName, e.lastName, e.age, e.employeeId );
  }

Но опять же, в однопоточная модель совершенно безопасна для использования геттеров / сеттеров.

PS Я настоятельно рекомендую вам купить эту книгу: Эффективная Java . Вы никогда не пожалеете об этом, и у вас будет информация, чтобы судить о лучших статьях, подобных цитированной.

20
ответ дан 3 December 2019 в 02:29
поделиться

"Шаблон JavaBeans имеет серьезные недостатки." - Джошуа Блох, Effective Java

Обожаю этих ребят. Вырывание произвольных цитат из контекста уже является для меня причиной не доверять такой статье.

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

Edit: См. пункт 2 ("Consider a builder when faced with many constructor parameters") в Effective Java на Google Books: http://books.google.com/books?id=ka2VUBqHiWkC&lpg=PP1&pg=PA11#v=onepage&q&f=false

4
ответ дан 3 December 2019 в 02:29
поделиться

Это совершенно безопасно и гораздо предпочтительнее, чем бесконечно вложенный java.util .Карта . Вы получаете безопасность типов, упрощаете понимание кода и избегаете попадания кода в The Daily WTF. Обратите внимание, что реализация должна быть разделена - не смешивайте слишком много логики (помимо простой проверки) в ваших классах хранения данных. Вы должны прочитать о POJO

0
ответ дан 3 December 2019 в 02:29
поделиться

Основная причина отказа от сеттеров - неизменяемость. Запрограммируйте неизменяемость заранее, и вы избежите проблем с потоками вокруг этих объектов.

Если вы получите конструктор, который читает

new Person ("param 1", "param 2", "param 3", "param 4", "param 5", "param 6", "param 7 "," param 8 ")

то ваш объект слишком сложен. Вам потребуются объекты Parameter (см. Книгу Мартина Фаулера по рефакторингу).

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

Если вам нужно изменить объект, добавьте конструктор копирования (т. Е. Метод клонирования). Современные JVM справляются с этим легко и достаточно быстро, и при этом есть небольшая потеря скорости. Вы также упрощаете работу с Hotspot и GC.

2
ответ дан 3 December 2019 в 02:29
поделиться

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

Сеттеры - это следующая лучшая вещь - не такое "чистое" ОО, но огромное удобство по сравнению с конструкторами, и они хорошо работают на практике.

Когда тесты начнут проваливаться из-за "плохих" java beans, тогда я пересмотрю причину для беспокойства. Но пока что я этого не видел. Единственное, когда я бы сказал, что они, вероятно, неуместны, - это использование общих бобов в многопоточном коде, поскольку синхронизация общего изменяемого состояния - дело непростое. Не допускайте этого, и бобы будут в самый раз.

0
ответ дан 3 December 2019 в 02:29
поделиться

Мое возражение против использования JavaBeans в качестве классов хранения данных состоит в том, что они допускают объекты с несогласованным состоянием. В типичном случае использования таких bean-компонентов у вас есть следующие шаги:

  • создать экземпляр класса;
  • установить первое свойство;
  • установить второе свойство;
  • ...
  • установить последнее свойство. свойство;
  • использовать экземпляр объекта.

Теперь ваш класс готов к использованию.Так в чем тут проблема? Между созданием экземпляра класса и установкой последнего свойства у вас есть объект, который находится во внутренне несовместимом или непригодном для использования состоянии, но ничто не мешает вам случайно его использовать. Я предпочитаю систему, в которой класс автоматически находится в согласованном, пригодном для использования состоянии при создании экземпляра. По этой причине я предпочитаю либо передать все начальное состояние в конструкторе, либо, если упомянутое начальное состояние слишком сложное, передать начальное состояние в виде хеш-карты или набора или тому подобное. Теперь сценарий варианта использования следующий:

  • (Необязательно: настроить объект параметров) ;
  • создать экземпляр класса;
  • использовать экземпляр объекта.

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

Конечно, такая установка лучше всего подходит для более простых объектов. Для более сложных объектов с такими вещами, как необязательные свойства и т. Д., Вы захотите пойти дальше и использовать что-то вроде шаблона Builder, на который вам указали другие. Строители хороши, когда у вас есть более сложные сценарии, IMO, но для более простой и понятной параметризации более чем достаточно просто использования аргументов конструктора или какого-либо объекта параметров.

6
ответ дан 3 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

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