Чи повинен складний вираз EL замінити одним яйцевим гетером?


10

Якщо у мене є компонент, який умовно візуалізує на основі кількох змінних, який є оптимальним способом обробки оператора render ... чи повинна логіка жити в декларації компонента або в якійсь формі допоміжного класу?

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

Варіант 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();
     }
...

Отже, обидва працюють ... але який це правильний спосіб впоратися зі сценарієм?


Для цього конкретного прикладу я б використав el. Здається, просто перегляньте пов’язані дані. Якщо у вашому коді Java є якась логіка, barking animalsя б викликав цей метод, оскільки він уже існує. Якщо ви використовуєте логіку перегляду, яку ви використовуєте на декількох сайтах, ви можете створити з неї функцію el.

Expression Language спочатку назвав просте вираження мови , так що може натякнути на його передбачуваному використанні. Мій власний погляд: якщо це логіка перегляду, 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 документах за допомогою функцій або інтерфейсу: парами, справді, здається, не мають можливості переносимості, ремонтопридатності та доказуваності реалізації Java-бобів.

Якщо розробник вільно володіє як EL, так і Java та володіє як xhtml, так і Java-бобами, здається, не має особливого сенсу використовувати EL для проведення будь-якої умовної оцінки розміром> 1.

Просто здається, що занадто багато переваг для реалізації на Java:

  • Можливість спертися на компілятор IDE +
  • Використовуйте константи або перерахунки (для "собаки" та "гавкіт"), ймовірно, вони також використовуються в коді в іншому місці для порівняння ... якщо значення String змінюється, це справжнє задоволення: потрібно вручну замінювати кожну появу його через кодова база
  • Замість того, щоб переходити на відповідну сторінку з відповідними даними, я можу використовувати логіку, використовуючи одиничні тести

Один з головних аргументів, які я чув (за межами Stack) на користь Варіанту 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: вибрати ... але я це бачив і раніше.

Зрештою, ця теоретично все ще є "переглядом" логіки, оскільки вона визначає, що насправді відображається, тому є концептуальний аргумент, який повинен жити в xhtml. Проблема, яку я виявив, полягає в тому, що включення такої логіки у шаблон перегляду може зробити макет набагато складнішим для розуміння в довгостроковій перспективі, і я ще не бачив, що цей метод вирішення проблеми має якусь реальну користь, ніж використання Java реалізація бобів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.