как избежать дублирования кода модели с помощью JSF и JPA - PullRequest
3 голосов
/ 13 июля 2010

Я новичок в JSF и мне интересно, правильно ли я все понял. Допустим, у меня есть простая CMS, которая позволяет писать страницы.

Сначала я определяю сущность JPA с именем Page:

@Entity
public class Page {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column
  private Long id;

  @Column private String title;

  @Column private String content;

  // getters & setters ...

}

Тогда я бы хотел создать Page-s. Для этого, похоже, мне нужен какой-то бин страницы. Пока я занимался такими вещами:

@Model
public class PageBean {

  private Page page = new Page();

    public String getTitle() {
      return page.getTitle();
    }

    public void setTitle(String title) {
      page.setTitle(title);
    }

    // rest of properties & getters & setters ...

    public void save() {
      // persist using EntityManager
    }
 }

У меня следующий вопрос: учитывая, что моя модель сущности JPA и модель, которую я хочу использовать в представлениях, в большинстве случаев совершенно одинаковы, есть ли способ избежать необходимости создавать партию геттеров? сеттеры в PageBean?

Я где-то читал, что вы не должны использовать один и тот же bean-компонент как сущность JPA и bean-компонент модели JSF (потому что JSF выполняет повторные вызовы геттеров, которые могут повлиять на JPA), но мне все же интересно, не существует ли более простого способа, который помог бы избежать этот вид дублирования кода. Особенно, когда у вас есть приложение с большой моделью и во многих случаях не требуется ничего особенного в bean-компонентах вида, похоже, что это может стать довольно громоздким.

Ответы [ 2 ]

4 голосов
/ 13 июля 2010

[...], учитывая, что моя сущностная модель JPA и модель, которую я хочу использовать в представлениях, в большинстве случаев совершенно одинаковы, есть ли способ избежать необходимости создавать партию геттеров& setters в PageBean?

Я не вижу смысла в использовании оболочки вокруг сущности и добавление такого слоя действительно является дублированием.Просто используйте объект со своей страницы JSF.Да, это создает некоторую связь между представлением и доменом, но, как правило, изменение базы данных обычно означает добавление или удаление полей в представлении.Другими словами, я не покупаю аргумент «развязки», и я написал достаточно дополнительных слоев, кода отображения, стандартного кода и т. Д., Чтобы по возможности использовать простой подход.

Я где-то читалчто вам не следует использовать один и тот же bean-компонент как сущность JPA и bean-компонент модели JSF (поскольку JSF выполняет повторные вызовы для получателей, которые могут повлиять на JPA)

Мне было бы интересно, если бы вы могли предоставить ссылку, ноКласс-обертка (делегирование вызовов объекту) ничего не изменит, если где-то возникнет проблема.

На всякий случай, некоторые дополнительные ресурсы:

2 голосов
/ 13 июля 2010

Это не дублирование кода.Алгоритмы не дублируются.Бизнес-логика все еще находится в одном месте.

То, что делает ваш компонент, просто соединяет модель View с доменом.Это хорошо, это часть паттерна MVC.

Если бы вы использовали вашу сущность JPA в качестве базового компонента, вы бы нарушили паттерн MVC.Например, если однажды вместо отображения простого String вам потребуется добавить Date к этому String, потому что представление требует этого (то есть требования к интерфейсу), вы собираетесь написать эту логику представления внутри JPAучебный класс?Это не имеет смысла, смешивая модель домена и модель представления.

С другой стороны, почему представление должно знать о том, как реализован домен?Что если формат значений домена изменится?(Например, вы экономите временную метку String вместо класса даты в базе данных для повышения производительности).Все, что вам нужно сделать, - это просто переписать метод в компоненте поддержки, для этого потребуется метка времени и адаптировать его к дате, чтобы все работало так, как было раньше.Только одно изменение вне класса JPA.Если бы у вас было это в классе JPA, вы бы в итоге поддерживали обе логики только в одном классе (логика интерфейса и логика домена).

Что если вы хотите разработать новое представление (например, для мобильной версии)?Ты собираешься добавить еще больше кода в класс JPA?Было бы лучше сохранить JPA как есть и создать еще один Bean (который расширяет общий bean для обоих представлений) для мобильной версии.

Если после всего этого вы все равно хотите не писать геттерыи сеттеры, вы можете сделать

#{myBean.page.title}

все, что вам нужно, это getPage() внутри поддерживающего боба.

...