Следует ли заменить сложное выражение EL одним геттером javabean?


10

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

Текст woof отображается только тогда, когда животное является слоном или собакой и животное не является немым.

Опция 1:

Реализация в представлении:

<h:outputText id="text" value="woof" 
  rendered="#{animal.type == 'elephant' 
                  or animal.type == 'dog' and not(animal.mute)}"/>

или вариант 2:

Инкапсуляция:

<h:outputText id="text" value="woof" rendered="#{animal.barkingAnimal}"/>

с реализацией:

public class Animal {
     public boolean isBarkingAnimal() {
         return ("dog".equals(getType()) || "elephant".equals(getType())) && !isMute();
     }
...

Так что оба работают ... но какой правильный способ справиться со сценарием?


Для этого конкретного примера я бы использовал эл. Кажется, просто для просмотра связанных данных. Если у вас есть логика в вашем Java-коде, barking animalsя бы вызвал этот метод, поскольку он уже существует. Если вы используете логику просмотра на нескольких сайтах, вы можете создать из нее функцию el.

Язык выражений первоначально назывался Простейшим возможным языком выражений, так что он может указывать на его предполагаемое использование. Мое собственное мнение: если это логика представления, EL может быть уместным; если это бизнес-логика, то это не так.
McDowell

Ответы:


5

В большинстве случаев это просто вопрос вкуса. Если ваша проблема заключается в повторном использовании условия, вы также можете сделать:

<ui:param name="animalCanBark" value="#{animal.type == 'elephant' 
              or animal.type == 'dog' and not(animal.mute)}" />
...
<h:outputText id="text" value="woof" rendered="#{animalCanBark}"/>

Это часто полезно, когда выражение, которое вам нужно написать, включает в себя более одного объекта, скажем:

<ui:param name="showBarking" value="#{animal.type == 'elephant'
              and not facesContext.validationFailed" />

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

Сказав это, если это информация о модели, которую когда-нибудь можно будет использовать в другом месте (а не просто на другой странице Facelets / JSF), это послужило бы хорошей причиной сделать это в вашем Java-коде. В приведенном вами примере метод isBarkingAnimal()дает некоторую информацию о модели ( Animal), которая когда-нибудь может оказаться полезной, когда другому объекту (не просто другой странице Facelets) необходимо узнать, лает ли данное животное. Так что я бы, наверное, пошел с этим.


3

Как правило, старайтесь сохранять файлы .xhtml как можно более свободными от логики, чтобы они имели дело только с представлением. Итак, четко перейти к варианту 2.


2
Нужно ли заботиться о модели? Если используется более чем один раз, почему бы альясинга его использования <c:set>или <ui:param>не быть вариант?

В этом примере нет модели логики. Вы бы сместили логику представления в логику модели, которая генерирует код Java, который даже не вызывается в Java. Если класс Animalнаходится в другой среде (удаленной) или программисты передают его просто неважно для него.

1

Лично я бы использовал вариант № 2. Несмотря на то, что я знаю, что решить проблему, используя EL, можно, и получить возможность повторного использования в документах xhtml, используя функции или пользовательский интерфейс: paras, на самом деле кажется, что в реализации Java-бина действительно нет переносимости, удобства сопровождения и тестируемости.

Если разработчик свободно владеет как EL, так и Java и владеет компонентами xhtml и Java, кажется, что не имеет смысла использовать EL для проведения ЛЮБОЙ условной оценки с размером> 1.

Кажется, что реализация на стороне Java имеет слишком много преимуществ:

  • Возможность опереться на IDE + компилятор
  • Используйте константы или перечисления (для «собака» и «кора»), есть вероятность, что они используются и в других местах кода для сравнений ... если значение String меняется, то очень интересно вручную заменять каждое его вхождение через кодовая база
  • Вместо того, чтобы переходить на соответствующую страницу с соответствующими данными, я могу использовать логику с помощью юнит-тестов.

Один из основных аргументов, которые я услышал (вне стека) в пользу варианта 1:

«Когда рендеринг компонента отображается намного проще, гораздо проще увидеть эту логику».

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

<h:outputText value="grrr" 
    render="#{animal.type == 'dog' or animal.type == 'cat' or animal.type == 'horse' 
        or animal.type == 'pony' or animal.type == 'mule' or animal.type == 'lion'
        or animal.type == 'tiger' or (animal.type == 'bird' 
        and animal.subType == 'macaw') or .... continue this for another line or two}"
/>

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

<h:outputText value="grr" render="#{theMonstrosityFromPreviousExample} />
<h:outputText value="cry" 
    render="#{animal.type == 'human' and animal.subType == 'baby'}" />
<h:outputText value="yo" 
    render="#{animal.type == 'human' and animal.subType == 'teenager'}" />
<h:outputText value="hello" 
    render="#{animal.type == 'human' and animal.subType == 'adult'}"/>

Может ли отображаться до 4 текстов одновременно? На первый взгляд вы не можете сказать, проверка каждого условия будет необходимо. В качестве примечания, я понимаю, что этот пример также плохой дизайн, поскольку их можно поместить в ac: select ... но я видел это раньше.

В конце концов, это теоретически логика «просмотра», поскольку она определяет, что на самом деле отображается, так что есть концептуальный аргумент, который должен существовать в xhtml. Проблема, которую я обнаружил, заключается в том, что включение логики, подобной этой, в шаблон представления, может сделать компоновку намного сложнее для понимания в долгосрочной перспективе, и мне еще предстоит увидеть, что этот метод решения проблемы дает реальное преимущество по сравнению с использованием Java. реализация бина.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.