Czy złożone wyrażenie EL powinno zostać zastąpione przez pojedynczy getter javabean?


10

W JSF, jeśli mam komponent, który warunkowo renderuje na podstawie wielu zmiennych, jaki jest optymalny sposób obsługi instrukcji renderowania ... czy logika powinna istnieć w deklaracji komponentu lub w jakiejś formie klasy pomocniczej?

Tekst woof jest wyświetlany tylko wtedy, gdy zwierzę jest słoniem lub psem, a zwierzę nie jest niemy.

Opcja 1:

Realizacja w widoku:

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

lub Opcja 2:

Kapsułkowanie:

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

z wdrożeniem:

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

Oba działają ... ale jaki jest właściwy sposób radzenia sobie ze scenariuszem?


W tym konkretnym przykładzie użyłbym el. Wydaje się, że są to tylko powiązane dane. Jeśli masz trochę logiki w kodzie java, barking animalsspowodowałbym wywołanie tej metody, ponieważ ona już istnieje. Jeśli używasz logiki widoku na wielu stronach, możesz zbudować z niej funkcję el.

Expression Language pierwotnie zwany najprostszy wyrażeń języka , dzięki czemu mogą wskazywać na jego zamierzonego użytkowania. Mój własny pogląd: jeśli jest to logika widoku, EL może być właściwe; jeśli jest to logika biznesowa, nie jest.
McDowell,

Odpowiedzi:


5

W większości przypadków jest to po prostu kwestia gustu. Jeśli Twoim problemem jest po prostu ponowne użycie tego warunku, możesz również:

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

Jest to często przydatne, gdy wyrażenie, które musisz napisać, dotyczy więcej niż jednego obiektu, powiedz:

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

Myślę, że wiele osób woli pisać tego rodzaju logikę w Javie zamiast w EL, ponieważ kompilator Java może sprawdzać typy w kodzie Java (również większość IDE ma lepsze autouzupełnianie dla Javy niż dla plików .XHTML), co jest problemem dla niektórych.

Powiedziawszy to, jeśli jest to informacja o modelu, która pewnego dnia może zostać użyta w innym miejscu (nie tylko na innej stronie Facelets / JSF), byłby to dobry powód, aby zrobić to w kodzie Java. W podanym przykładzie metoda isBarkingAnimal()podaje pewne informacje o modelu ( Animal), które pewnego dnia mogą okazać się przydatne, gdy inny obiekt (nie tylko kolejna strona Faceletów) musi wiedzieć, czy dane zwierzę szczeka. Więc pewnie poszedłbym z tym.


3

Zasadniczo staraj się, aby pliki .xhtml były jak najbardziej logiczne, aby zajmowały się tylko prezentacją. Więc wyraźnie wybierz opcję 2.


2
Czy to logika, na której model powinien się przejmować? Jeśli użyjesz go więcej niż raz, dlaczego miałbyś aliować go przy użyciu, <c:set>czy <ui:param>nie?

W tym przykładzie nie ma logiki modelowej. Przesunąłbyś logikę widoku na logikę modelu, która generuje kod Java, który nie jest nawet wywoływany w Javie. Jeśli klasa Animalznajduje się w innym środowisku (zdalnie) lub programiści podają jej po prostu nieistotny dla niej.

1

Osobiście skorzystałbym z Opcji # 2. Chociaż wiem, że bardzo możliwe jest rozwiązanie problemu za pomocą EL i ponowne wykorzystanie w dokumentach xhtml za pomocą funkcji lub interfejsu użytkownika: params, naprawdę wydaje się, że brakuje przenośności, łatwości konserwacji i testowania implementacji bean Java.

Jeśli programista posługuje się biegle zarówno językiem EL, jak i Javą i posiada zarówno komponenty Xhtml, jak i Java, nie ma sensu używać EL do DOWOLNEJ oceny warunkowej o rozmiarze> 1.

Wydaje się, że implementacja po stronie Java ma zbyt wiele zalet:

  • Możliwość oparcia się na kompilatorze IDE +
  • Używaj stałych lub wyliczeń (dla „psa” i „szczekania”), są szanse, że są one używane w innym miejscu w kodzie również do porównań ... jeśli zmienia się wartość ciągu, to naprawdę fajnie jest ręcznie wymieniać każde jej wystąpienie w podstawa kodu
  • Zamiast przechodzić do odpowiedniej strony z odpowiednimi danymi, mogę ćwiczyć logikę za pomocą testów jednostkowych

Jednym z głównych argumentów, które słyszałem (poza Stack) na korzyść Opcji 1, jest:

„O wiele łatwiej jest zobaczyć, kiedy komponent renderuje, jeśli zachowasz tę logikę w widoku”.

Przekonałem się, że może tak być w przypadku aplikacji na początkowym etapie życia, w której jest ona lżejsza i mniej skomplikowana. Jednak stosowanie tej praktyki na większą skalę i w miarę dojrzewania mniejszej aplikacji może spowodować, że szczury staną się warunkowe i mogą stać się koszmarem do utrzymania. Oto kilka przykładów podobnych do tego, co widziałem na wolności:

<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}"
/>

Lub mój ulubiony, używając wielu komponentów z warunkami renderowania, które wykluczają się, aby reprezentować różne wartości, które mogą być wyświetlane:

<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'}"/>

Czy można wyświetlić do 4 tekstów jednocześnie? Na pierwszy rzut oka nie można powiedzieć, konieczne będzie sprawdzenie każdego warunku. Na marginesie, zdaję sobie sprawę, że ten przykład jest również kiepskim projektem, ponieważ można je umieścić w ac: wybierz ... ale widziałem to wcześniej.

Na koniec dnia jest to teoretycznie logika „podglądu”, ponieważ określa ona, co faktycznie zostanie wyświetlone, więc istnieje argument koncepcyjny, który powinien znajdować się w pliku xhtml. Problem, który znalazłem, polega na tym, że włączenie takiej logiki w szablonie widoku może znacznie utrudnić zrozumienie układu na dłuższą metę i jeszcze nie widziałem, aby ta metoda rozwiązania problemu miała jakąkolwiek realną korzyść w porównaniu z użyciem Javy wdrożenie fasoli.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.