2011-01-16 16 views
7

Mój były kolega rozpoczął dyskusję pół godziny temu na temat JavaBeans i dlaczego nie działały tak, jak chce w JSF. Szczególny przypadek dotyczy właściwości boolowskich.JavaBeans i introspekcja - pomieszane właściwości boolowskie i indeksowane?

. Dla właściwości Boolean nazwie isUrl Eclipse generuje ten

private boolean isUrl; 
public boolean isUrl() {..} 
public boolean setUrl(boolean url) {..} 

Ale to nie działa w JSF. Zrobił to działa dodając public boolean getIsUrl() Wdrożenie może być wadliwa, więc zróbmy pewien, kto ma rację, za pomocą API introspekcję .:

BeanInfo info = Introspector.getBeanInfo(ClassTest.class); 
for (PropertyDescriptor pd : info.getPropertyDescriptors()) { 
     System.out.println(pd.getName() + ": " + pd.getReadMethod() + 
     " : " + pd.getWriteMethod()); 
} 

Na powyższym kodzie, to drukuje obie metody - czyli Eclipse ma rację, JSF jest źle. Ale brzmiało to podejrzanie, ponieważ the specification nie wspomina nic o podwójnym "jest".

Ale podczas przeglądania specyfikacji zobaczyłem coś, czego nigdy nie używałem - tak zwane indeksowane właściwości. Możesz mieć private String[] bar, a następnie public String getBar(int idx). A więc:

. Próbowałem tego z Introspector i nie znalazłem metody odczytu paska. Wynik powyższego kodu: bar: null : null. Więc przyszło mi do głowy - teraz introspector nie stosuje się do specyfikacji. Być może nie podążyło to w poprzednim przypadku i ostatecznie JSF ma rację. W rzeczywistości właściwości indeksowane mogą sprawić, że istnieją dwie metody odczytu dla danej właściwości. I nie jest to możliwe w klasie PropertyDescriptor API introspekcji.

Na co to nas zaprowadzi - mamy prawdopodobnie uszkodzony API, który nie jest zgodny ze specyfikacją. Co prowadzi do innych implementacji specyfikacji (oczywiście JSF używa niestandardowego). Co prowadzi do dalszych nieporozumień i pomyłek.

Świadczy o tym, co mi przeszkadzało - w specyfikacji JavaBeans nazywają konwencje nazewnictwa dla metod "wzorców projektowych". Brzmi to źle dla mnie.

Więc teraz na pytania:

  1. jest spec jasne
  2. JavaBeans jest API introspekcji poprawne
  3. jest specyfikacja nowych JavaBeans potrzebne, przynajmniej do wyjaśnienia zachowania wartości logiczne (to subiektywny w pewnym zakresie)

Aktualizacja. wydaje się, że użycie JSF to raczej bean.isUrl niż bean.url. Co sprawia, że ​​perfekci czują, że nie działają z akcesorium isUrl().

P.S. JDK 1.6.0_20, JSF 1.2, MyFaces

+0

może coś w rodzaju właściwości C# będzie przydatny. – Bozho

+0

Po przeczytaniu kodu introspektora, isXxxx powinien działać. Nazwa użytego pola nie ma znaczenia. Czy próbowałeś aktualizacji Java 6 23? –

Odpowiedz

2

Jak wspomniano w @Peter Lawrey, nazwa pola jest nieistotna w odniesieniu do JavaBeans. Nie musi nawet istnieć, lub możesz nadać mu głupią nazwę, na przykład prefiks z m_.

Nie podano odpowiednich metod odczytu lub zapisu dla właściwości bar jako całości, więc nie będą one wyświetlane. Nie można zsyntetyzować obiektu Method do istniejącej klasy w środowisku wykonawczym.Uważam, że indeksowane właściwości były późną edycją, mimo że nie ma widocznej wartości @since, więc nie są używane przez interfejsy java.beans.

Nie mam specyfikacji JSF (i będzie ona za ścianą prawnika jcp.org), więc nie wiem, co ona twierdzi. Może on określać coś innego niż specyfikacja JavaBeans [prawdopodobne], lub możesz używać implementacji z błędami [prawdopodobnie również].

"Wzór projektu" to tylko fraza. Jak we wzorze, który występuje w naszym projekcie. To nie jest wzór projektu, jak w GoF.

+0

+1. Tak, "nieistotność" nazwy pola jest czymś, do czego doszliśmy w dyskusji, a to wyjaśnia zachowanie Eclipse i introspektora. Eclipse jest po prostu sprytny. O wzorcach projektowych - Zgadzam się, że to tylko fraza, ale to ona otrzymała bardzo konkretne znaczenie - takie, jakie podaje GoF. Nie znaczy to, że nie może oznaczać niczego innego, ale jest po prostu dziwne. – Bozho

4

Właściwości Java Bean definiuje się metodami, a nie polami. Z tego powodu klasa PropertyDescriptor ma metody getReadMethod() i getWriteMethod(), ale nie metody.

Osobiście uważam, że twój kolega stosuje złe praktyki.

a) is jest czasownikiem. Pola nie powinny być nazwane po czasownikach.
b), podczas gdy nie jest to wymagane, dobrą praktyką jest nazwa pola jak własność, która pozwala pisać kod tak:

PropertyDescriptor pd; // let's assume this is set 
Method referenceMethod = pd.getReadMethod() == null 
    // at least one of these is not null 
    ? pd.getWriteMethod() : pd.getReadMethod(); 
Field underLyingField = referenceMethod 
          .getDeclaringClass() 
          .getDeclaredField(pd.getName()); 

Chociaż ten kod nie jest znormalizowany, jest następujące konwencje i może przyjść bardzo przydatny. Jeśli nie stosujesz takich konwencji, nie masz możliwości skojarzenia pola z właściwością (co jest celowe, wiem).

np. Używam kod jak wyżej, aby sprawdzić, czy pole ma adnotacji


O właściwości indeksowanych:

Można użyć składni indeksu w tablicy lub listy (lub mapie) właściwości, ale tylko wtedy, gdy są one określone jako standardowe właściwości ziarna.

Więc jeśli mają właściwość takiego:

private String[] bar; 
public String[] getBar(){ 
    return bar; 
} 
public void setBar(String[] bar){ 
    this.bar = bar; 
} 

lub tak:

private List<String> bar; 
public List<String> getBar(){ 
    return bar; 
} 
public void setBar(List<String> bar){ 
    this.bar = bar; 
} 

można uzyskać dostęp do pierwszego członu z wyrażeniem ${bar[0]}

I z właściwością mapie tak:

private Map<String, String> bar; 
public Map<String, String> getBar(){ 
    return bar; 
} 
public void setBar(Map<String, String> bar){ 
    this.bar = bar; 
} 

Możesz uzyskać dostęp do wartości odwzorowanej na "baz", tak jak to ${bar['baz']}.

Ta funkcja opiera się na standardowej funkcjonalności fasoli, dlatego wymaga regularnych programów pobierających/ustawiających.

+0

(+1).ogólnie, zgadzam się, że właściwość boolowska nie powinna zawierać 'is', ale dla mnie ma sens, jeśli nazwa pola jest rzeczownikiem, a nie przymiotnikiem. – Bozho

+1

@Bhoho zabawne, myślałem, że to bardzo dobrze przyjęta konwencja, że ​​nazwy pól nie powinny być czasownikami, ale nie mogę znaleźć niczego, co by to poparło. Wszyscy mówią, że nazwa metody powinna być czasownikiem, a dla mnie oznacza to, że pole nie powinno, ale nikt nie mówi tak wyraźnie (ani Sun, Wikipedia, Joshua Bloch) –