Struktura fasoli wspierającej JSF (najlepsze praktyki)

118

Mam nadzieję, że w tym poście będę mógł poznać opinie ludzi na temat najlepszych praktyk dotyczących interfejsu między stronami JSF i zapasowymi komponentami bean.

Jedną rzeczą, na której nigdy nie mogę się zdecydować, jest struktura mojej fasoli. Ponadto nigdy nie znalazłem dobrego artykułu na ten temat.

Jakie właściwości mają poszczególne fasole? Kiedy należy dodać więcej właściwości do danego ziarna, w przeciwieństwie do tworzenia nowego ziarna i dodawania do niego właściwości? Czy w przypadku prostych aplikacji ma sens posiadanie tylko jednego ziarna zapasowego dla całej strony, biorąc pod uwagę złożoność związaną z wprowadzaniem jednego ziarna do drugiego? Czy fasola zapasowa powinna zawierać jakąkolwiek rzeczywistą logikę biznesową, czy też powinna zawierać wyłącznie dane?

Zapraszam do odpowiedzi na te i inne pytania, które mogą się pojawić.


Jeśli chodzi o zmniejszenie sprzężenia między stroną JSF a komponentem bean zapasowym, nigdy nie zezwalam stronie JSF na dostęp do właściwości właściwości zapasowego komponentu bean. Na przykład nigdy nie pozwalam na coś takiego jak:

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

Zawsze potrzebuję czegoś takiego:

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

o wartości ziarna wypełniającego:

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

Kiedy zapętlam kolekcję, używam klasy opakowującej, aby na przykład uniknąć drążenia obiektu w tabeli danych.

Ogólnie takie podejście wydaje mi się „właściwe”. Pozwala to uniknąć jakiegokolwiek sprzężenia między widokiem a danymi. Proszę popraw mnie jeżeli się mylę.

Zack Marrapese
źródło
Czy możesz podać przykład dla: Kiedy zapętlam kolekcję, używam klasy opakowującej, aby na przykład uniknąć drążenia w obiekcie w tabeli danych.
Koray Tugay
2
Aby uzyskać więcej informacji, zobacz odpowiedź BalusC na stackoverflow.com/questions/7223055/…
Zack Marrapese

Odpowiedzi:

146

Możesz to sprawdzić: rozróżnienie między różnymi rodzajami fasoli zarządzanych przez JSF .

Oto opis różnych rodzajów ziaren, zgodnie z definicją w powyższym artykule Neila Griffina:

  • Model Managed-Bean : Zwykle zakres sesji. Ten typ fasoli zarządzanej uczestniczy w problematyce „Model” wzorca projektowego MVC. Kiedy zobaczysz słowo „model” - pomyśl DANE. Komponent bean modelu JSF powinien być obiektem POJO zgodnym ze wzorcem projektowym JavaBean z właściwościami enkapsulującymi pobierające / ustawiające. Najczęstszym przypadkiem użycia fasoli modelu jest jednostka bazy danych lub po prostu reprezentowanie zestawu wierszy z zestawu wyników zapytania do bazy danych.
  • Backing Managed-Bean : zwykle żądaj zakresu. Ten typ zarządzanej fasoli bierze udział w problemie „Widok” wzorca projektowego MVC. Celem komponentu bean zapasowego jest obsługa logiki interfejsu użytkownika i ma relację 1: 1 z widokiem JSF lub formularzem JSF w kompozycji Facelet. Chociaż zwykle ma właściwości w stylu JavaBean ze skojarzonymi metodami pobierającymi / ustawiającymi, są to właściwości widoku, a nie bazowego modelu danych aplikacji. Fasola zapasowa JSF może również zawierać metody JSF actionListener i valueChangeListener.
  • Fasola zarządzana przez kontroler : zwykle żądaj zakresu. Ten typ zarządzanej fasoli uczestniczy w „kontrolerze” wzorca projektowego MVC. Celem komponentu bean kontrolera jest wykonanie jakiejś logiki biznesowej i zwrócenie wyniku nawigacji do modułu obsługi nawigacji JSF. Ziarna kontrolera JSF zwykle mają metody akcji JSF (a nie metody actionListener).
  • Obsługa zarządzanego komponentu Bean : zwykle zakres sesji lub aplikacji. Ten typ fasoli „obsługuje” jeden lub więcej widoków w obszarze „Widok” wzorca projektowego MVC. Typowym przypadkiem użycia jest dostarczenie ArrayList do JSF h: selectOneMenu rozwijanych list, które pojawiają się w więcej niż jednym widoku JSF. Jeśli dane na listach rozwijanych są szczególne dla użytkownika, fasola będzie utrzymywana w zakresie sesji. Jeśli jednak dane dotyczą wszystkich użytkowników (na przykład listy rozwijane prowincji), to ziarno zostanie zachowane w zakresie aplikacji, dzięki czemu będzie można je buforować dla wszystkich użytkowników.
  • Utility Managed-Bean : zwykle zakres aplikacji. Ten typ fasoli zapewnia pewien rodzaj funkcji „narzędziowej” dla jednego lub większej liczby widoków JSF. Dobrym przykładem może być komponent bean FileUpload, którego można ponownie użyć w wielu aplikacjach internetowych.
cecemel
źródło
8
To świetny artykuł. Nigdy wcześniej tego nie widziałem i zdecydowanie się cieszę, że to opublikowałeś. Ktokolwiek to przegłosował, jest szalony. To nie jest specyficzne dla iceFaces.
Zack Marrapese
2
Wydaje się, że nie ma linku do aktualnego artykułu.
Bill Rosmus,
Kopię można znaleźć tutaj
ChrLipp
10
Mimo to nie mogę dojść do tego, że ta odpowiedź ma obecnie 71 głosów za. Ktokolwiek zaimplementował swoją aplikację JSF zgodnie z tymi zasadami, niewątpliwie później musi narzekać na to, że JSF jest strasznie nieprzejrzystym frameworkiem, a ich aplikacje JSF są wielkim bałaganem w kodzie i wszyscy winią JSF zamiast własnego złego podejścia opartego na niewłaściwych lekcjach i tak zwanych „najlepsze praktyki”.
BalusC
czy któryś z tych elementów logicznych jest wykonywany w przeglądarce zamiast na serwerze?
eskalera,
14

Świetne pytanie. Wiele cierpiałem z tym samym dylematem, kiedy przeniosłem się do JSF. To naprawdę zależy od twojej aplikacji. Pochodzę ze świata Java EE, więc radziłbym mieć jak najmniej logiki biznesowej w twoich kopiach zapasowych. Jeśli logika jest wyłącznie związana z prezentacją strony, dobrze jest mieć ją w fasoli.

Uważam, że jedną z (wielu) mocnych stron JSF jest fakt, że można eksponować obiekty domeny bezpośrednio na zarządzanych komponentach bean. Dlatego zdecydowanie polecam to <:outputText value="#{myBean.anObject.anObjectProperty}" />podejście, w przeciwnym razie wykonasz zbyt dużo pracy, ręcznie eksponując każdą nieruchomość. Co więcej, wprowadzanie lub aktualizowanie danych byłoby trochę bałaganem, gdybyś hermetyzował wszystkie właściwości. Istnieją sytuacje, w których pojedynczy obiekt domeny może nie być wystarczający. W takich przypadkach przygotowuję ValueObject przed wystawieniem go na fasoli.

EDYCJA: Właściwie, jeśli zamierzasz hermetyzować każdą właściwość obiektu, którą chcesz ujawnić, zalecałbym zamiast tego powiązanie składników interfejsu użytkownika z ziarnem zapasowym, a następnie wstrzyknięcie zawartości bezpośrednio do wartości składnika.

Jeśli chodzi o strukturę fasoli, punktem zwrotnym dla mnie było to, że siłą zignorowałem wszystkie rzeczy, które wiedziałem o tworzeniu aplikacji internetowych i zacząłem traktować je jako aplikację GUI. JSF bardzo naśladuje Swinga i dlatego najlepsze praktyki tworzenia aplikacji Swing miałyby zastosowanie głównie do tworzenia aplikacji JSF.

Allan Lykke Christensen
źródło
Dzięki za wgląd. Nigdy tak naprawdę nie robiłem zbyt wiele w zakresie aplikacji swingowych (poza projektami akademickimi dawno temu). Jakie są dobre zasady aplikacji swingowych? Poza tym, dlaczego jest bałagan podczas wstawiania i aktualizowania wartości? wydaje mi się to samo?
Zack Marrapese,
5

Myślę, że najważniejszą rzeczą w przypadku twoich fasoli jest oddzielenie ich logiki. Jeśli masz stronę tytułową systemu CMS, uważałbym za złą praktykę umieszczanie każdego fragmentu kodu w jednym ziarnie, ponieważ:

  1. W końcu fasola stanie się bardzo duża
  2. Inni ludzie mogą łatwiej znaleźć to, czego szukają, jeśli rozwiązują problemy ze stroną logowania, jeśli wtedy mogą łatwo odszukać plik loginBean.java.
  3. Czasami masz małe fragmenty funkcjonalności, które wyraźnie różnią się od reszty twojego kodu. Wyobrażam sobie, że oddzielając je, ułatwiłbyś sobie przebudowę / rozszerzenie tego kodu na coś większego, kiedy masz już fajną fasolę z dobrym Struktura.
  4. Posiadanie 1 dużej fasoli, aby zrobić wszystko, sprawi, że będzie on bardziej zależny od pamięci, jeśli / kiedy będziesz musiał wykonywać deklaracje takie jak ta MyBigBean bigBean = new MyBigBean (); zamiast używać funkcji, której faktycznie potrzebujesz, wykonując LoginBean loginBean = new LoginBean (); (Popraw mnie, jeśli się mylę ???)
  5. Moim zdaniem oddzielanie ziaren jest jak oddzielanie metod. Nie potrzebujesz jednej dużej metody, która obsługuje ponad 100 linii, ale raczej podziel ją na nowe metody, które obsługują ich określone zadanie.
  6. Pamiętaj, najprawdopodobniej ktoś inny niż ty będzie musiał również pracować nad projektami JSF.


Jeśli chodzi o sprzężenie, to nie uważam, aby zezwalanie stronom JSF na dostęp do właściwości obiektów w backingbean nie było kłopotliwe. To jest wsparcie, które jest wbudowane w JSF i naprawdę po prostu ułatwia czytanie i budowanie imo. Już oddzielałeś ściśle logikę MVC. Robiąc to, oszczędzasz sobie mnóstwo linii z getterami i seterami w twoim backingbean. Na przykład mam naprawdę ogromny obiekt przekazany mi przez serwisy internetowe, w których muszę użyć pewnych właściwości w mojej prezentacji. Gdybym utworzył getter / setter dla każdej właściwości, mój bean rozszerzyłby się o co najmniej 100 dodatkowych wierszy zmiennych i metod uzyskiwania właściwości. Używając wbudowanej funkcjonalności JSF, oszczędzam mój czas i cenne linie kodu.

Tylko moje 2 centy dotyczące tego, nawet z pytaniem już oznaczonym jako odpowiedź.

Chris Dale
źródło
1
jeśli jednak masz ogromny obiekt, który znajduje się w ziarnie fasoli i masz - powiedzmy - 15 funkcji EL wbijających się w ten obiekt ze strony JSF, jesteś teraz przywiązany nie tylko do fasoli, ale do tego obiektu. Dlatego trudno będzie usunąć ten obiekt bez uszkadzania interfejsu użytkownika.
Zack Marrapese
1
Ale czy twoja fasola nie będzie również przywiązana do tego przedmiotu? A Twój interfejs użytkownika jest powiązany z fasolką? Kiedy będziesz musiał go zmodyfikować, będziesz musiał zmienić wszystkie metody pobierające / ustawiające zarówno w interfejsie użytkownika, jak i fasoli.
Chris Dale,
4

Mogę nie odpowiedzieć na każde Twoje pytanie, ponieważ niewiele z nich wydaje się zależnych od każdego przypadku.

  • Dobrze jest mieć logikę biznesową w fasoli wspierającej. To zależy, skąd pochodzisz. Jeśli ćwiczysz projektowanie oparte na domenie, pojawi się pokusa dołączenia logiki biznesowej do zapasowego komponentu bean lub może to być również logika trwałości. Twierdzą, że dlaczego tak głupi obiekt. Obiekt powinien nosić nie tylko stan, ale także zachowanie. Z drugiej strony, jeśli weźmiesz pod uwagę tradycyjny sposób wykonywania zadań w języku Java EE, możesz mieć ochotę na posiadanie danych w fasoli bazowej, która może być również komponentem bean encji, a także inną logiką biznesową i trwałości w niektórych ziarnach sesji lub czymś podobnym. To też jest w porządku.

  • Dobrze jest mieć jedną fasolkę podkładową na całą stronę. Nie widzę żadnego problemu z tym samym. Może to nie wyglądać dobrze, ale to zależy od przypadku.

  • Twoje drugie pytanie jest znacznie bardziej zależne od sprawy, którą masz w ręku. Wolałbym tutaj kierować się domeną, może być właściwe dodanie właściwości do istniejącej lub w inny sposób utworzenie nowej fasoli. Który lepiej pasuje. Myślę, że nie ma na to srebrnej kuli.

  • Jakie właściwości należą do której fasoli. Cóż, czy to nie zależy od obiektu domeny? A może pytanie nie jest takie jasne.

Ponadto w podanym przykładzie kodu nie widzę żadnej dużej korzyści.

Adeel Ansari
źródło
jeśli - na przykład - mielibyśmy przejść z używania domowych POJO utworzonych za pomocą zapytań JDBC na encje Hibernate, które mają nieco inne nazwy pól, musielibyśmy zmienić nie tylko fasolę zapasową. Musielibyśmy również zmienić stronę JSF. Nie tak z moim przykładem kodu. Po prostu zmień fasolę.
Zack Marrapese,
W takim przypadku możesz stworzyć swoje wspierające fasole, byty. wtedy wystarczy zmienić strony JSF. A może to zależy, dlaczego mimo wszystko miałbyś zmieniać nazwy nieruchomości? miałoby to sens tylko wtedy, gdy zmienisz nazwę pola, aby pasowała do nazwy kolumny bazy danych. Ale to zupełnie inny przypadek.
Adeel Ansari
4

Nie musiałbym mieć tylko jednego ziarna zapasowego na stronę. To zależy od funkcjonalności, ale przez większość czasu miałem po jednym ziarnie na stronę, ponieważ głównie jedna strona obsługuje jedną funkcję. Na przykład na stronie mam link do rejestracji (połączę się z RegisterBean) i link do koszyka zakupów (ShoopingBasketBean).

Używam tego <: outputText value = "# {myBean.anObject.anObjectProperty}" />, ponieważ zwykle zachowuję kopie fasoli jako fasolki akcji, które przechowują obiekt danych. Nie chcę pisać opakowania w moim zapasowym komponencie bean, aby uzyskać dostęp do właściwości moich obiektów danych.

Bhushan Bhangale
źródło
0

Lubię testować kod biznesowy bez View, więc uważam BackingBeans za interfejsy od widoku do kodu modelu. Nigdy nie umieszczam żadnej reguły ani procesu w BackingBean. Ten kod trafia do usług lub pomocników, umożliwiając ponowne wykorzystanie.

Jeśli używasz walidatorów, umieść je z BackingBean i odwołaj się do nich z metody walidacji.

Jeśli uzyskujesz dostęp do DAO w celu wypełnienia selekcji, radia, pól wyboru, rób to zawsze z bazy danych.

Uwierz mi!. Możesz wstrzyknąć JavaBean do BackingBean, ale spróbuj wstrzyknąć BackingBean do innego. Wkrótce będziesz miał kłopoty z konserwacją i zrozumieniem kodu.

jjruiz
źródło