2011-01-16 2 views
7

전직 동료가 30 분 전에 JavaBeans에 대한 토론을 시작했으며, JSF에서 원하는 방식으로 작동하지 않는 이유는 무엇입니까? 특별한 경우는 부울 속성에 관한 것입니다.JavaBeans 및 내부 검사 - 부울 및 색인 된 속성에서 엉망이 되었습니까?

. isUrl 이클립스라는 부울 속성이

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

를 생성하지만이 JSF에서 작동하지 않습니다. 그는이 버그가있을 수 있습니다 구현을 public boolean getIsUrl() 추가하여 작동, 그래서 위의 코드에 대한 반성의 API :

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

를 사용하여, 바로 누구인지는,이 두 가지 방법을 인쇄 할 수 있도록했다 - 즉, 이클립스, JSF 권리 잘못된 것입니다. 그러나 그것은 the specification이 이중 "is"에 대해 언급하지 않았기 때문에 나에게 의심스러운 것으로 들렸다.

하지만 스펙을 살펴볼 때, 내가 사용하지 않은 것을 - 인덱스 된 속성이라고합니다. private String[] barpublic String getBar(int idx)을 가질 수 있습니다. 따라서 :

. Introspector으로 시도했지만 바에 대한 읽기 방법을 찾지 못했습니다. 위 코드의 결과는 bar: null : null입니다. 그래서 생각했습니다. 이제 인트로 스펙터는 스펙을 따르지 않습니다. 아마 이전 사례에서 그것을 따르지 않았고 궁극적으로 JSF가 옳습니다. 실제로 인덱스 속성은 특정 속성에 대해 두 가지 읽기 메서드가 있도록 만들 수 있습니다. 그리고 이것은 내성 API 인 PropertyDescriptor 클래스로는 불가능합니다.

무엇이 우리를 이끌 었는지 - 사양에 맞지 않는 API가 손상되었을 수 있습니다. 이는 사양의 다른 구현으로 이어집니다 (JSF는 분명히 맞춤 설정을 사용합니다). 그 결과 더 많은 오해와 혼란이 야기됩니다.

JavaBeans 스펙에서 "디자인 패턴"메소드의 이름 지정 규칙을 호출합니다. 이것은 나에게 잘못된 것처럼 들린다.

그래서, 지금 질문에 :

  1. 분명히 자바 빈즈 스펙을 정정 반성의 API
  2. 필요한 새로운 자바 빈즈 사양입니다입니다, 적어도 그건 (부울의 동작을 명확히 범위에 주관적 임)

업데이트. JSF 사용이 bean.url이 아닌 bean.isUrl 인 것으로 나타납니다. 접근 코드가 isUrl() 인 경우 완벽한 기능이 작동하지 않습니다.

P. JDK 1.6.0_20, JSF 1.2, MyFaces

+0

아마도 C# 속성과 같은 것이 유용 할 것입니다. – Bozho

+0

introspector 코드를 읽은 후 isXxxx가 작동해야합니다. 사용 된 필드 이름은 중요하지 않습니다. Java 6 업데이트 23을 사용해 보셨습니까? –

답변

2

@Peter Lawrey가 언급했듯이, JavaBeans에 관한 한 필드 이름은 관련이 없습니다. 존재할 필요가 없으며, 접두어로 m_과 같은 바보 같은 이름을 붙일 수 있습니다.

전체적으로 bar 속성에 대해 적절한 읽기 또는 쓰기 메소드를 제공하지 않았으므로 표시되지 않습니다. 런타임시 기존 클래스에 Method을 합성 할 수 없습니다.인덱스 된 속성은 늦은 버전이라고 생각합니다. @since이 없기 때문에 java.beans 인터페이스에서는 사용하지 않습니다.

JSF 사양이 없으므로 (jcp.org 변호사 벽 뒤에 있습니다.) 소유권 주장이 무엇인지 모릅니다. JavaBeans 스펙 [probable]과 다른 것을 지정하거나, 버그가있는 구현을 사용 중일 수 있습니다.

"디자인 패턴"은 단지 문구 일뿐입니다. 우리의 디자인에서 나타나는 패턴에서와 같이. GoF처럼 디자인 패턴이 아닙니다.

+0

+1. 예, 필드 이름의 "관련성 없음"은 토론에서 도착한 것으로, 이클립스와 인트로 스펙터의 동작을 설명합니다. 이클립스는 영리하다. 디자인 패턴 정보 - 나는 그저 하나의 구절에 동의하지만, 매우 구체적인 의미를 지닌 것입니다 - GoF가 제공 한 것입니다. 그것이 다른 무엇을 의미 할 수는 없지만 그것은 이상합니다. – Bozho

4

Java Bean 등록 정보는 메소드가 아니라 필드로 정의됩니다. 이러한 이유로 PropertyDescriptor 클래스는 getReadMethod()getWriteMethod() 메서드를 가지지 만 getField() 메서드는 없습니다.

개인적으로 나는 동료가 나쁜 습관을 사용하고 있다고 생각합니다.

a) is은 동사입니다. 필드의 동사 이름을 지정하면 안됩니다.

이 코드가 표준화되지는 않지만
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()); 

,이 따르고 규칙을하고 올 수가 필요 아니지만
b)는 좋은 연습이 같은 코드를 작성할 수 있습니다 재산과 같은 필드를 이름을 지정하는 것입니다 매우 편리합니다. 이와 같은 규칙을 따르지 않는다면 필드를 부동산과 연관시킬 방법이 없습니다 (이는 의도적 인 것입니다).

나는 필드 주석 인덱스 속성에 대한


이 있는지 확인하기 위해 위와 같이 코드를 사용

당신은 배열 또는 목록 (또는 맵) 특성에 인덱스 구문을 사용할 수 있습니다,하지만 경우에만 그들은 정의 표준 빈 특성으로.

그래서 당신은이 같은 속성이있는 경우 :

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

당신이 표현 ${bar[0]}

와지도 속성을 첫 번째 멤버에 액세스 할 수 있습니다

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

또는 같은

이렇게 :

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

과 같이 "baz"에 매핑 된 값에 액세스 할 수 있습니다.

이 기능은 표준 빈 기능을 기반으로하므로 일반 getter/setter가 필요합니다.

+0

(+1)일반적으로 부울 속성에는'is'가 포함되어서는 안된다는 것에 동의하지만 필드 이름이 형용사가 아닌 명사이면 의미가 있습니다. – Bozho

+1

@Bozho 재미 있군요, 나는 필드 이름이 동사가 아니어야한다는 매우 받아 들여진 규칙이라고 생각했지만 그 주장을 뒷받침 할만한 것을 찾을 수는 없습니다. 모두는 메소드 이름이 동사 여야하며, 필드는 그렇지 않아야 함을 의미하는 나에게 말해야하지만 아무도 그렇게 명시 적으로 말하지 않습니다 (Sun, Wikipedia, Joshua Bloch) –