2013-02-10 2 views
3

저는 빌더 패턴에 매우 관심이 있습니다. 자주 사용하지만 빌더를 만드는 사람이 충분한 지 잘 모르며, 사용할 수있는 모든 환경에 대해 의구심이 있습니다. .올바른 장소에서 올바른 작성자를 사용하십시오.

Person person = new Person.Builder() 
     .withName("John") 
     .withSecondName("Smith") 
     .withAge(50) 
     .build(); 
     System.out.println(person); 
여기

내 의심의 일부 :

  • 당신이 생각하십니까 그것이 정말 그냥 빨리 사용 예를

    public class Person { 
    
        private String name; 
        private String secondName; 
        private int age; 
    
        public static class Builder { 
         private boolean isBuilt; 
         private Person person = new Person(); 
    
         private void check() { 
          if (isBuilt) { 
           throw new IllegalStateException(
             "The object cannot be modified after built"); 
          } 
         } 
    
         public Builder withName(String name) { 
          check(); 
          person.name = name; 
          return this; 
         } 
    
         public Builder withSecondName(String secondName) { 
          check(); 
          person.secondName = secondName; 
          return this; 
         } 
    
         public Builder withAge(int age) { 
          check(); 
          person.age = age; 
          return this; 
         } 
    
         public Person build() { 
          check(); 
          isBuilt = true; 
          return person; 
         } 
        } 
    
        @Override 
        public String toString() { 
         return "Name: " + name + "\nSecond name:" + secondName + "\nAge:" + age; 
        } 
    } 
    

    : 이 내가 빌더를 만드는 방법의 예입니다 불변의 경우, 어떻게하면 좋습니까?

  • 스레드 안전성 정보. 글쎄, 아마도 이것이 나의 주된 의심 일 것이다. 이 스레드가 실제로 안전합니까? 인터넷에서 클래스 수준 변수가 최종적이어야하며 생성자를 통해 전달되어야한다고 예를 보았습니다. 또한 변수가 변수로 선언 된 예제를 보았습니다. 당신이 그것에 대해 어떻게 생각하십니까?
  • 이 빌더를 사용할 수있는 시나리오와 관련하여이 빌더에 제한이 있다고 생각합니까? 내 말은 EJB, JSF backing bean, MDB에서 호출되거나 JPA 엔티티가되는 것이 적합할까요?
+1

'빌더'는'Person'과 같은 필드를 가지고 있어야하고'Person'의 모든 필드는'final'이어야합니다. –

+0

나는 이것이 옴니버스 질문 인 것을 좋아하지 않습니다. "내 코드를 어떻게 생각하니?"또는 "어떻게 이름을 지어야하는지"와 같은 주관적인 질문을 제거하는 것도 고려해야합니다. – millimoose

+0

@LouisWasserman이 링크를 한번 보시면 저도 이런 식으로 누군가를 발견했습니다. 중복을 제거하고 싶지만 잘 모릅니다 : http://xavimiro.blogspot.ie/2008/04/new-builder-pattern.html 그는 'volatile'키워드를 권장하지만 스레드 안전에 관해서는 완전히 유효 할 지 확신 할 수 없습니다. – sfrj

답변

1

정말 불변이라고 생각합니까? [...] 정말 실 안전합니까?

코드의 어떤 부분도 변경할 수 없습니다. 이것은 또한 스레드 안전을 방해 할 수 있습니다. 클래스가 바이너리 방식으로 쓰레드에 안전한지 아닌지를 선언하는 것은 정말로 어렵다. 또한 왜 처음부터 스레드간에 빌더 인스턴스를 공유 할 것인지 모르겠지만 코드 샘플의 단순함으로 인해 오도 될 수 있습니다.

스레드 안전성을 높이려면 Builder을 직접 변경할 수 없습니다. 즉, 모든 withXXX() 메소드는 새 상태를 나타내는 새 빌더를 리턴해야합니다. (아마도 더 똑똑한 방법이 있지만 직접적인 접근 방법이 될 것입니다.)

반복해서 말하면 : 빌더를 스레드로부터 안전하게 만드는 것이 반드시 필요한지는 잘 모르겠습니다. 매우 짧은 수명과 가시 범위를 가진 물체. 불변으로 만들 수 있는지 여부는 유스 케이스에 따라 다르지만, 부분적으로 채워진 빌더를 저장하는 것이 좋지만, 이는 다소 드문 경우입니다. (하나의 이름이 set로 시작 반대로 주관적는하지만, 이름이 with로 시작 현재 위치에서 개체를 수정할 수 없습니다하는 방법에 대한보다 직관적 보인다.)

은이 빌더가있을 것이라고 생각하십니까 그것이 사용될 수있는 시나리오와 관련하여 어떤 제한이 있습니까?

이것은 일반적으로 대답 할 수없는, 그러나 당신이 당신의 빌더하여 Person 객체는 불변, 따라서 단지 작도하게한다면, 그들은 JPA 엔티티로 사용할 수 있습니다, 내 생각 엔뿐만 아니라 JSF의 백업 콩과 같습니다. 특정 객체를 생성/관리하는 Java 프레임 워크는 자바 빈즈가 될 것으로 예상하지 않는 것보다 더 자주 사용됩니다. 즉, 리 객체를 통해 no-args 생성자 및 속성 설정자를 호출하여 이러한 객체를 만들 수 있습니다.

+0

답해 주셔서 감사합니다. JPA와 JSF에 대한 언급에서 매우 흥미 롭습니다. JPA에서 제공하는 대안은 Pojos를 주입 할 수있는'CDI'라고 생각합니다. 그것에 대해 어떻게 생각하세요? 당신은 아마도 그것을 구현하는 더 영리한 방법이있다, 당신이 작은 예제로 답변을 업데이 트하면 감사하겠습니다. – sfrj

+0

@sfrj 더 영리한 방법은 어떤 유형의 작업이 유효한지를 나타내는 협력적인 'XxxBuilder'중 하나를 반환하는 것과 같은 일을하는 것입니다. 본질적으로 당신은'withXxx()'메소드가 상태 전이이고'build()'메소드가 터미널 상태가되는 빌더와 함께 객체 생성을 나타내는 상태 머신을 모델링합니다. 귀하의 예제처럼 데이터 구조를 구축하는 것이 실용적인 것인지 잘 모르겠습니다. (또는 빌더 패턴이 실제인지 데이터 구조로 시작하는.) – millimoose

+0

@sfrj "나는 가정 JPA에서 제공하는 대안은 POJO를 주입 할 수 있습니다 CDI입니다. 당신이 그것에 대해 어떻게 생각하십니까?" - Java EE 기술을 설명 할 수 있도록 주위에 임의의 유행어를 던지고있는 것 같습니다. 하지만 어쨌든. CDI가 JPA에서 어떤 식 으로든 제공되는 것을 보지 못했습니다. CDI에서 JPA 엔티티를 만들 수 있는지 의심 스럽습니다. 그래서 두 가지를 연결하는 이유를 모르겠습니다. CDI는 생성자 삽입을 지원하기 때문에 불변의 백업 빈을 관리 할 수도 있지만 여전히 빌더에 의해 빌드되지 않으므로 그다지 중요하지 않습니다. – millimoose

관련 문제