Структура компонента поддержки JSF (лучшие практики)

118

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

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

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

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


Что касается уменьшения связи между страницей JSF и компонентом поддержки, я никогда не разрешаю странице JSF обращаться к каким-либо свойствам свойств компонента поддержки. Например, я никогда не разрешаю такие вещи, как:

<h:outputText value="#{myBean.anObject.anObjectProperty}" />

Мне всегда нужно что-то вроде:

<h:outputText value="#{myBean.theObjectProperty}" />

со значением компонента поддержки:

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}

Когда я перебираю коллекцию, я использую класс-оболочку, чтобы, например, не углубляться в объект в таблице данных.

В целом такой подход мне кажется "правильным". Это позволяет избежать какой-либо связи между представлением и данными. Пожалуйста, поправьте меня, если я ошибаюсь.

Зак Маррапез
источник
Можете ли вы привести пример: когда я перебираю коллекцию, я использую класс-оболочку, чтобы, например, не углубляться в объект в таблице данных.
Корай Тугай
2
Дополнительные сведения см. В ответе BalusC на странице stackoverflow.com/questions/7223055/…
Зак Маррапез

Ответы:

146

Возможно, вы захотите проверить это: различать разные типы управляемых компонентов JSF .

Вот описание различных типов bean-компонентов, определенных в вышеприведенной статье Нила Гриффина:

  • Управляемый компонент модели : обычно объем сеанса. Этот тип управляемого bean-компонента участвует в проблеме «Модель» шаблона проектирования MVC. Когда вы видите слово «модель» - думайте ДАННЫЕ. Бин-модель JSF должен быть POJO, который следует шаблону проектирования JavaBean с инкапсулирующими свойствами геттеров / сеттеров. Наиболее распространенный вариант использования bean-компонента модели - это быть объектом базы данных или просто представлять набор строк из набора результатов запроса к базе данных.
  • Резервное копирование управляемого компонента : обычно объем запроса. Этот тип управляемого bean-компонента участвует в функции «Просмотр» шаблона проектирования MVC. Назначение компонента поддержки - поддерживать логику пользовательского интерфейса и имеет отношение 1 :: 1 с представлением JSF или формой JSF в композиции Facelet. Хотя он обычно имеет свойства в стиле JavaBean со связанными с ними геттерами / сеттерами, это свойства представления, а не базовой модели данных приложения. Компоненты поддержки JSF могут также иметь методы JSF actionListener и valueChangeListener.
  • Контроллер Managed-Bean : Обычно область запроса. Этот тип управляемого bean-компонента участвует в «контроллере» шаблона проектирования MVC. Назначение bean-компонента контроллера - выполнить некую бизнес-логику и вернуть результат навигации обработчику навигации JSF. Бины-контроллеры JSF обычно имеют методы действий JSF (а не методы actionListener).
  • Поддержка управляемого компонента : обычно сеанс или область приложения. Этот тип bean-компонента "поддерживает" одно или несколько представлений в отношении "View" шаблона проектирования MVC. Типичный вариант использования - это предоставление в JSF раскрывающихся списков h: selectOneMenu ArrayList, которые появляются более чем в одном представлении JSF. Если данные в раскрывающихся списках относятся к конкретному пользователю, то компонент будет храниться в области сеанса. Однако, если данные применяются ко всем пользователям (например, раскрывающиеся списки провинций), то компонент будет храниться в области приложения, чтобы его можно было кэшировать для всех пользователей.
  • Утилита Managed-Bean : Обычно область применения. Этот тип bean-компонента предоставляет некоторую "служебную" функцию для одного или нескольких представлений JSF. Хорошим примером этого может быть bean-компонент FileUpload, который можно повторно использовать в нескольких веб-приложениях.
cecemel
источник
8
Это замечательная статья. Я никогда его раньше не видел и определенно рад, что вы его разместили. Тот, кто проголосовал против этого, сумасшедший. Это не специально для iceFaces.
Зак Маррапез,
2
Ссылка на настоящую статью, похоже, исчезла.
Bill Rosmus
Копию можно найти здесь
ChrLipp
10
Тем не менее, я не могу понять, что этот ответ в настоящее время получил 71 одобрение. Кто бы ни реализовал свое приложение JSF в соответствии с этими правилами, несомненно, впоследствии должен разглагольствовать о том, что JSF является ужасно непрозрачной структурой, а их приложения JSF - большим беспорядком кода, и все они винят сам JSF, а не свой собственный плохой подход, основанный на неправильных уроках и так называемом "лучшие практики" изучены.
BalusC
Выполняется ли какая-либо логика этих компонентов в браузере, а не на сервере?
eskalera
14

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

Я считаю, что одной из (многих) сильных сторон JSF на самом деле является то, что вы можете предоставлять объекты домена непосредственно в управляемых bean-компонентах. Поэтому я настоятельно рекомендую этот <:outputText value="#{myBean.anObject.anObjectProperty}" />подход, иначе вы будете слишком много работать для себя, вручную раскрывая каждое свойство. Более того, если бы вы инкапсулировали все свойства, это было бы немного беспорядком при вставке или обновлении данных. Бывают ситуации, когда одного объекта домена может быть недостаточно. В таких случаях я готовлю ValueObject перед тем, как выставить его на bean-компонент.

РЕДАКТИРОВАТЬ: На самом деле, если вы собираетесь инкапсулировать каждое свойство объекта, которое хотите раскрыть, я бы порекомендовал вам вместо этого привязать компоненты пользовательского интерфейса к поддерживающему bean-компоненту, а затем ввести содержимое непосредственно в значение компонента.

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

Аллан Ликке Кристенсен
источник
Спасибо за понимание. Я никогда особо не занимался разработкой приложений Swing (кроме академических проектов давным-давно). Какие хорошие принципы работы с приложениями Swing? Кроме того, почему при вставке и обновлении значений возникает беспорядок? мне кажется таким же?
Зак Маррапез,
5

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

  1. Боб со временем станет очень большим
  2. Другим людям легче найти то, что они ищут, если они устраняют неполадки на странице входа в систему, если тогда они могут легко найти файл loginBean.java.
  3. Иногда у вас есть небольшие функциональные возможности, которые четко отличаются от остальной части вашего кода, и я полагаю, что, разделив их, вы упростите себе переработку / расширение этого кода во что-то большее, когда у вас уже есть хороший bean-компонент с хорошим структура.
  4. Наличие 1 большого bean-компонента для всего этого сделает его более зависимым от памяти, если / когда вам нужно будет делать такие объявления, как это MyBigBean bigBean = new MyBigBean (); вместо того, чтобы использовать funksjonality, в котором вы действительно нуждаетесь, выполнив LoginBean loginBean = new LoginBean (); (Поправьте меня, если я ошибаюсь ???)
  5. На мой взгляд, разделение бобов похоже на разделение методов. Вам не нужен один большой метод, который запускает более 100 строк, а скорее разделите его на новые методы, которые обрабатывают их конкретную задачу.
  6. Помните, что, скорее всего, над вашими JSF-проектами, скорее всего, придется работать не только вам.


Что касается связи, я не вижу проблем в том, чтобы разрешить вашим JSF-страницам доступ к свойствам объектов в вашем backingbean. Эта поддержка встроена в JSF и действительно упрощает чтение и сборку imo. Вы уже строго разделяете логику MVC. Сделав это, вы сэкономите массу строк с помощью геттеров и сеттеров в своем backingbean. Например, у меня есть действительно огромный объект, предоставленный мне веб-службами, и мне нужно использовать некоторые свойства в моей презентации. Если бы я создал геттер / сеттер для каждого свойства, мой компонент расширился бы, по крайней мере, на 100 дополнительных строк переменных и методов для получения свойств. Благодаря использованию встроенных функций JSF мое время и драгоценные строки кода экономятся.

Только мои 2 цента по этому поводу, даже если вопрос уже отмечен как ответ.

Крис Дейл
источник
1
однако, если у вас есть огромный объект, который находится в вашем bean-компоненте, и у вас есть, скажем, 15 EL-функций, копающихся в этом объекте со страницы JSF, вы теперь привязаны не только к bean-компоненту, но и к этому объекту. Поэтому удалить этот объект без нарушения пользовательского интерфейса будет сложно.
Зак Маррапез
1
Но не будет ли ваш поддерживающий компонент также привязан к этому объекту? А ваш UI привязан к бобу поддержки? Когда вам нужно будет изменить его, вам придется изменить все ваши геттеры / сеттеры как в пользовательском интерфейсе, так и в bean-компоненте.
Крис Дейл,
4

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

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

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

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

  • Какие свойства принадлежат какому компоненту поддержки. Ну разве это не зависит от доменного объекта? Или, может быть, вопрос не так ясен.

Более того, в данном примере кода я не вижу огромной выгоды.

Адил Ансари
источник
если, например, мы должны были перейти от использования самодельных POJO, созданных с помощью запросов JDBC, на сущности Hibernate с немного разными именами полей, нам пришлось бы не только изменить компонент поддержки. Нам также придется изменить страницу JSF. Не так с моим примером кода. Просто поменяйте фасоль.
Зак Маррапез,
В этом случае вы можете создать свои бобы поддержки, сущности. тогда вам просто нужно изменить страницы JSF. Или это зависит от того, зачем вам все равно менять название свойств? это будет иметь смысл только тогда, когда вы переименуете поле в соответствии с именем столбца вашей базы данных. Но это совсем другой случай.
Адил Ансари
4

Мне не нужно держать только один компонент поддержки на странице. Это зависит от функциональности, но в большинстве случаев у меня был один bean-компонент на страницу, поскольку в основном одна страница обрабатывает одну функциональность. Например, на странице у меня есть ссылка для регистрации (я буду ссылаться на RegisterBean) и ссылка на корзину для покупок (ShoopingBasketBean).

Я использую это <: outputText value = "# {myBean.anObject.anObjectProperty}" />, поскольку обычно поддерживаю bean-компоненты как компоненты действий, которые содержат объект данных. Я не хочу писать оболочку в моем поддерживающем компоненте для доступа к свойствам моих объектов данных.

Бхушан Бхангале
источник
0

Мне нравится тестировать бизнес-код без View, поэтому я рассматриваю BackingBeans как интерфейсы от View к коду модели. Я никогда не помещал никаких правил или процессов в BackingBean. Этот код переходит в Сервисы или Помощники, позволяя повторно использовать.

Если вы используете валидаторы, поместите их из BackingBean и ссылайтесь на них из своего метода проверки.

Если вы получаете доступ к DAO для заполнения Selects, Radios, Checkboxes, делайте это всегда из BackingBean.

Поверь мне!. Вы можете внедрить JavaBean в BackingBean, но попробуйте внедрить BackingBean в другой. Скоро вы столкнетесь с проблемой обслуживания и понимания кода.

jjruiz
источник