JSF 지원 빈 구조 (모범 사례)


118

이 게시물에서 JSF 페이지와 백킹 빈 간의 인터페이스에 대한 모범 사례에 대한 사람들의 의견을 얻을 수 있기를 바랍니다.

내가 결코 정착 할 수없는 한 가지는 내 백킹 빈의 구조입니다. 게다가 나는 그 주제에 대한 좋은 기사를 찾지 못했습니다.

어떤 속성이 어떤 백업 빈에 속합니까? 새 빈을 만들고 속성을 추가하는 것과는 반대로 주어진 빈에 더 많은 속성을 추가하는 것이 적절한시기는 언제입니까? 간단한 애플리케이션의 경우 하나의 빈을 다른 빈에 주입하는 것과 관련된 복잡성을 고려할 때 전체 페이지에 대해 단일 백킹 빈을 갖는 것이 합리적입니까? 백킹 빈은 실제 비즈니스 로직을 포함해야합니까, 아니면 데이터를 엄격하게 포함해야합니까?

이러한 질문과 다른 질문에 자유롭게 대답하십시오.


JSF 페이지와 백킹 빈 사이의 결합을 줄이기 위해 JSF 페이지가 백킹 빈 속성의 속성에 액세스하는 것을 허용하지 않습니다. 예를 들어 다음과 같은 것은 허용하지 않습니다.

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

나는 항상 다음과 같은 것이 필요합니다.

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

백업 Bean 값은 다음과 같습니다.

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

컬렉션을 반복 할 때 예를 들어 데이터 테이블의 개체로 드릴 다운하지 않도록 래퍼 클래스를 사용합니다.

일반적으로이 접근 방식은 나에게 "옳다"고 느낍니다. 뷰와 데이터 간의 결합을 방지합니다. 내가 틀렸다면 나를 고쳐주세요.


예를 들면 다음과 같습니다. 컬렉션을 반복 할 때, 예를 들어 데이터 테이블의 개체로 드릴 다운하지 않도록 래퍼 클래스를 사용합니다.
Koray Tugay 2013

답변:


146

당신은 이것을 확인하고 싶을 것입니다 : 서로 다른 종류의 JSF 관리 빈들을 구별하기 .

다음은 Neil Griffin의 위 기사에서 정의한 다양한 Bean 유형에 대한 설명입니다.

  • Model Managed-Bean : 일반적으로 세션 범위. 이러한 유형의 관리 빈은 MVC 디자인 패턴의 "모델"문제에 참여합니다. "모델"이라는 단어를 볼 때-DATA를 생각하십시오. JSF 모델 빈은 속성을 캡슐화하는 getter / setter가있는 JavaBean 디자인 패턴을 따르는 POJO 여야합니다. 모델 빈의 가장 일반적인 사용 사례는 데이터베이스 엔티티이거나 단순히 데이터베이스 쿼리의 결과 집합에서 행 집합을 나타내는 것입니다.
  • Backing Managed-Bean : 일반적으로 범위를 요청합니다. 이러한 유형의 관리 빈은 MVC 디자인 패턴의 "보기"문제에 참여합니다. backing-bean의 목적은 UI 로직을 지원하는 것이며 JSF보기 또는 Facelet 구성의 JSF 양식과 1 :: 1 관계를 갖습니다. 일반적으로 관련 getter / setter가있는 JavaBean 스타일 속성이 있지만 기본 응용 프로그램 데이터 모델이 아닌 View의 속성입니다. JSF backing-bean은 JSF actionListener 및 valueChangeListener 메소드도 가질 수 있습니다.
  • Controller Managed-Bean : 일반적으로 범위를 요청합니다. 이러한 유형의 관리 빈은 MVC 디자인 패턴의 "컨트롤러"문제에 참여합니다. 컨트롤러 빈의 목적은 일종의 비즈니스 로직을 실행하고 탐색 결과를 JSF 탐색 처리기에 반환하는 것입니다. JSF 컨트롤러 빈에는 일반적으로 JSF 작업 메서드가 있습니다 (actionListener 메서드가 아님).
  • Managed-Bean 지원 : 일반적으로 세션 또는 애플리케이션 범위. 이 유형의 bean은 MVC 디자인 패턴의 "보기"관련에서 하나 이상의보기를 "지원"합니다. 일반적인 사용 사례는 둘 이상의 JSF보기에 나타나는 JSF h : selectOneMenu 드롭 다운 목록에 ArrayList를 제공하는 것입니다. 드롭 다운 목록의 데이터가 사용자에게 특정한 경우 Bean은 세션 범위에 유지됩니다. 그러나 데이터가 모든 사용자에게 적용되는 경우 (예 : 지방의 드롭 다운 목록) Bean은 모든 사용자에 대해 캐시 될 수 있도록 애플리케이션 범위에 유지됩니다.
  • Utility Managed-Bean : 일반적으로 애플리케이션 범위입니다. 이 유형의 Bean은 하나 이상의 JSF보기에 일부 유형의 "유틸리티"기능을 제공합니다. 이에 대한 좋은 예는 여러 웹 애플리케이션에서 재사용 할 수있는 FileUpload Bean 일 수 있습니다.

8
이것은 훌륭한 기사입니다. 나는 그것을 전에 본 적이 없으며 당신이 그것을 게시하게되어 기쁩니다. 이 투표를 한 사람은 미친 짓입니다. iceFaces에만 국한되지 않습니다.
Zack Marrapese

2
실제 기사에 대한 링크가 사라진 것 같습니다.
Bill Rosmus 2012

사본은 여기
ChrLipp

10
그래도이 답변이 현재 71 개 찬성이라는 것을 알 수 없습니다. 이러한 규칙에 따라 JSF 애플리케이션을 구현 한 사람은 의심 할 여지없이 JSF가 엄청나게 불투명 한 프레임 워크이고 JSF 애플리케이션이 큰 코드 엉망이며 모두 잘못된 교훈과 소위 말하는 잘못된 접근 방식 대신 JSF 자체를 비난해야합니다. "모범 사례"를 배웠습니다.
BalusC 2013-08-13

이 Bean의 논리 중 하나가 서버 대신 브라우저에서 실행됩니까?
eskalera 2014

14

좋은 질문입니다. JSF로 옮겼을 때도 똑같은 딜레마로 많은 고통을 겪었습니다. 실제로 응용 프로그램에 따라 다릅니다. 저는 Java EE 세계 출신이므로 가능한 한 백킹 빈에 비즈니스 로직을 적게 사용하는 것이 좋습니다. 논리가 순전히 페이지의 표현과 관련이 있다면, backing bean에있는 것이 좋습니다.

JSF의 (많은) 강점 중 하나는 실제로 관리 빈에서 직접 도메인 개체를 노출 할 수 있다는 사실입니다. 따라서 <:outputText value="#{myBean.anObject.anObjectProperty}" />접근 방식을 강력히 권장합니다 . 그렇지 않으면 각 속성을 수동으로 노출하는 데 너무 많은 작업을 수행하게됩니다. 또한 모든 속성을 캡슐화하면 데이터를 삽입하거나 업데이트 할 때 약간 엉망이 될 것입니다. 단일 도메인 개체로 충분하지 않을 수있는 상황이 있습니다. 그런 경우에는 ValueObject 를 빈에 노출하기 전에 준비합니다 .

편집 : 실제로 노출하려는 모든 개체 속성을 캡슐화하려는 경우 대신 UI 구성 요소를 백업 빈에 바인딩 한 다음 콘텐츠를 구성 요소의 값에 직접 삽입하는 것이 좋습니다.

빈 구조 측면에서 전환점은 웹 애플리케이션 구축에 대해 알고있는 모든 것을 강제로 무시하고 대신 GUI 애플리케이션으로 취급하기 시작했을 때였습니다. JSF는 Swing을 많이 모방하므로 Swing 응용 프로그램을 개발하기위한 모범 사례는 대부분 JSF 응용 프로그램 빌드에도 적용됩니다.


귀하의 통찰력에 감사드립니다. 나는 스윙 애플리케이션 방식에서 많은 일을 한 적이 없습니다 (오래 전의 학술 프로젝트 외에는). 스윙 적용의 좋은 원칙은 무엇입니까? 또한 값을 삽입하고 업데이트 할 때 왜 엉망입니까? 나에게 똑같은 것 같습니까?
Zack Marrapese 2009

5

백킹 빈에서 가장 중요한 것은 논리를 분리하는 것입니다. CMS 시스템의 첫 페이지가 있다면 다음과 같은 이유로 모든 코드를 하나의 빈에 넣는 것이 나쁜 습관이라고 생각합니다.

  1. 콩은 결국 매우 커질 것입니다
  2. 다른 사람들이 로그인 페이지의 문제를 해결하는 경우 찾고있는 내용을 쉽게 찾을 수 있습니다. 그러면 loginBean.java 파일을 쉽게 찾을 수 있습니다.
  3. 때로는 코드의 나머지 부분과 명확하게 구별되는 작은 기능이 있습니다. 이것을 분리하면이 코드를 더 큰 것으로 재개발 / 확장하는 것이 더 쉬워 질 것입니다. 구조.
  4. 1 개의 큰 빈이 있으면 모든 작업을 수행하기 위해 다음과 같은 선언을 수행해야하는 경우 더 많은 메모리 의존성을 갖게됩니다. MyBigBean bigBean = new MyBigBean (); 실제로 필요한 funksjonality를 사용하는 대신 LoginBean loginBean = new LoginBean (); (여기서 내가 틀렸다면 정정 해줘 ???)
  5. 제 생각에는 콩을 분리하는 것은 방법을 분리하는 것과 같습니다. 100 줄이 넘는 큰 방법을 원하지는 않지만 특정 작업을 처리하는 새로운 방법으로 분할합니다.
  6. 당신이 아닌 다른 사람도 당신의 JSF 프로젝트에 참여해야한다는 것을 기억하십시오.


커플 링에 관해서는 JSF 페이지가 backingbean의 객체 속성에도 액세스 할 수 있도록하는 문제로 보지 않습니다. 이것은 JSF에 내장 된 지원이며 실제로 imo를 읽고 빌드하는 것을 더 쉽게 만듭니다. MVC 로직을 엄격하게 분리하는 모든 준비. 이를 통해 backingbean에서 getter 및 setter를 사용하여 수많은 라인을 절약 할 수 있습니다. 예를 들어, 웹 서비스에서 제공하는 정말 거대한 개체가 있는데, 프레젠테이션에서 몇 가지 속성을 사용해야합니다. 각 속성에 대해 getter / setter를 만들면 속성을 얻기위한 변수와 메서드가 최소 100 줄 이상 늘어납니다. 내장 된 JSF 기능을 사용하면 시간과 귀중한 코드 라인이 절약됩니다.

이미 답변으로 표시된 질문에도 불구하고 이것에 대해 2 센트 만.


1
그러나 빈에 거대한 객체가 있고 JSF 페이지에서 해당 객체를 파헤치는 15 개의 EL 함수가 있다면 이제 빈뿐만 아니라 해당 객체에 묶여 있습니다. 따라서 UI를 깨지 않고 해당 개체를 제거하기가 어렵습니다.
Zack Marrapese 2009

1
하지만 백킹 빈도 그 객체에 묶여 있지 않습니까? 그리고 당신의 UI는 backing bean에 묶여 있습니까? 그런 다음 수정해야 할 때 UI와 Bean 모두에서 모든 게터 / 세터를 변경해야합니다.
Chris Dale

4

경우에 따라 매우 의존하는 사람이 거의 없기 때문에 모든 질문에 답하지 못할 수도 있습니다.

  • 백킹 빈에 비즈니스 로직이 있으면 괜찮습니다. 어디에서 왔는지에 따라 다릅니다. 도메인 중심 설계를 연습하는 경우 비즈니스 로직을 백킹 빈에 포함 시키거나 지속성 로직이 될 수도 있습니다. 그들은 왜 그렇게 멍청한 대상이라고 주장합니다. 객체는 상태뿐만 아니라 동작도 전달해야합니다. 반면에 전통적인 Java EE 방식의 작업을 고려한다면 백킹 빈 (엔티티 빈이 될 수도 있음)에 데이터가 있고 일부 세션 빈이나 기타 비즈니스 및 지속성 논리에 데이터가있는 것처럼 느껴질 수 있습니다. 그것도 괜찮습니다.

  • 전체 페이지에 대해 단일 백업 빈을 갖는 것은 완벽합니다. 이것만으로는 아무런 문제가 없습니다. 이것은 옳지 않은 것처럼 보일 수 있지만 경우에 따라 다릅니다.

  • 당신의 다른 질문은 당신이 가지고있는 사건에 훨씬 더 의존적입니다. 여기에서 도메인 중심으로 이동하는 것을 선호합니다. 기존에 속성을 추가하거나 그렇지 않으면 새 빈을 만드는 것이 적절할 수 있습니다. 어느 쪽이 더 적합합니다. 나는 이것에 대한 은색 총알이 없다고 생각합니다.

  • 백업 Bean에 속하는 특성 글쎄, 그것은 도메인 개체에 의존하지 않습니까? 또는 질문이 명확하지 않을 수 있습니다.

또한 주어진 코드 예제에서 큰 이점을 보지 못했습니다.


예를 들어, JDBC 쿼리로 생성 된 자체 제작 POJO 사용에서 필드 이름이 약간 다른 Hibernate 엔터티로 변경하려면 백킹 빈만 변경해야하는 것은 아닙니다. JSF 페이지도 변경해야합니다. 내 코드 예제에서는 그렇지 않습니다. 그냥 콩을 바꾸십시오.
Zack Marrapese 2009

이 경우 백킹 빈, 엔티티를 만들 수 있습니다. 그런 다음 JSF 페이지를 변경하기 만하면됩니다. 아니면 어쨌든 속성의 이름을 변경하는 이유에 따라 다릅니다. 데이터베이스 열 이름과 일치하도록 필드 이름을 바꿀 때만 의미가 있습니다. 그러나 그것은 완전히 다른 경우입니다.
Adeel Ansari

4

페이지 당 하나의 백킹 빈만 유지할 필요는 없습니다. 기능에 따라 다르지만 대부분 한 페이지가 하나의 기능을 처리하기 때문에 페이지 당 하나의 빈을 가졌습니다. 예를 들어 페이지에 등록 링크 (RegisterBean과 링크)와 쇼핑 바구니 링크 (ShoopingBasketBean)가 있습니다.

이 <: outputText value = "# {myBean.anObject.anObjectProperty}"/>를 사용합니다. 일반적으로 Bean을 데이터 객체를 보유하는 작업 Bean으로 계속 백업합니다. 데이터 개체의 속성에 액세스하기 위해 백업 빈에 래퍼를 작성하고 싶지 않습니다.


0

저는 View없이 비즈니스 코드를 테스트하는 것을 좋아하므로 BackingBeans를 View에서 Model 코드로의 인터페이스로 생각합니다. BackingBean에 규칙이나 프로세스를 넣지 않았습니다. 이 코드는 서비스 또는 도우미로 이동하여 재사용 할 수 있습니다.

유효성 검사기를 사용하는 경우 BackingBean에서 꺼내고 유효성 검사 메서드에서 참조하십시오.

Selects, Radios, Checkbox를 채우기 위해 DAO에 액세스하는 경우 항상 BackingBean에서 수행하십시오.

나를 믿어!. JavaBean을 BackingBean에 주입 할 수 있지만 BackingBean을 다른 것에 주입 해보십시오. 곧 유지 관리 및 코드 이해의 악몽에 빠질 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.