2013-08-24 3 views
-2

Ruby (Rails) 프로그래머는 2 년 동안 Java를 사용하는 다른 팀으로 전환했습니다. 자바 빌더 패턴에 대해 몇 가지 질문이 있습니다.빌더 패턴 작동 방법

이 패턴을 사용하면 얻을 수있는 이점을 이해할 수 있습니다. 즉, 텔레 스코핑 생성자와 일관성없는 상태를 만드는 Java Bean Setter를 피하는 것이지만 정확히 어떻게 작동하는지 이해하는 데 어려움이 있습니다. 다음은 정확한 패턴입니다. 사용

public class Person 
{ 
    //why is it so important that this be final, hence immutable 
    private final String firstName; 
    private final String lastName; 

    // Constructor 
    public Person(String firstName, String lastName) 
    { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    //I have absolutely no idea what is this for and why is this necessary 
    public static Builder builder() 
    { 
     return new Builder(); 
    } 

    //This is an inner class, where person is the outer class (the owning class) 
    //but why is this has to be a static class? 
    public static class Builder 
    { 
     private String firstName; 
     private String lastName; 

     public Builder withFirstName(String firstName) 
     { 
      //this.firstName refers to the Builder instance firstName 
      this.firstName = firstName; 
      return this; 
      //what is this return this? returning this instance of the Builder object? 
     } 

     public Builder withLastName(String lastName) 
     { 
      this.lastName = lastName; 
      return this; 
     } 

     public Person build() 
     { 
      return new Person(firstName, lastName); 
      //firstName and lastName here refer to the Builder's object instance vars, 
      //and used to create a new person object 
     } 
    } 
} 

를 사용하려면 :

Person p = new Person.Builder(5).firstName("foo").lastName("bar").build(); 

1)에 대한 빌더에 PARAM "5"는 무엇입니까?

2) 빌더 내부 클래스가 정적 인 이유는 무엇입니까?

3) public static Builder builder() 메소드의 용도는 무엇입니까?

4) 우리는 실제로 새로운 내부 클래스를 작성하고 있음을 수정합니까?이 내부 클래스의 빌드 메소드가 새 Person 객체를 리턴하는 Builder 객체?

5)이 Person 클래스를 생성 한 것처럼 보입니다. 메모리 사용량을 두 배로 늘려야합니다. 하나는 외부 클래스 용이고 다른 하나는 내부 클래스 용입니다.

6) Person p = new Person ("foo", "bar")에 의해 새로운 person 객체를 만들 수 있다고 정정합니다.

7) 누군가가 어떻게 이것을 테스트합니까? 세터와 게터를 단위 테스트하는 방법?

8) 필드에서 유효성 검사를 수행 할 수 있습니까?

9) 필드가 필요하다는 것을 어떻게 지정해야합니까? 누군가 firstName만으로 빌드를 시도했지만 lastName이 제공되지 않은 경우 예외가 발생합니다.

미리 감사드립니다.

+1

한 번 디자인 패턴을 읽으려고 시도 했습니까? 당신은 당신의 대답을 얻을 것입니다. – Lokesh

+1

[wiki 기사] 읽기 (http://en.m.wikipedia.org/wiki/Builder_pattern) – Bohemian

답변

1
  1. 나는 이것을 얻지 못한다. Builder 클래스에는 정의 된 생성자가 없으므로 컴파일러가 매개 변수없는 클래스를 자동으로 생성합니다.

  2. Builder 클래스가 정적이 아닌 경우 내부 클래스에 액세스하려면 둘러싼 클래스의 인스턴스가 필요합니다. 이것은 "닭고기와 계란"문제 일 것입니다. 내부 클래스는 외부 클래스의 인스턴스를 가져 오는 데 사용되지만, 먼저 외부 클래스의 인스턴스를 사용해야합니다. static 수정자를 사용하면 외부 클래스의 인스턴스를 사용하지 않아도됩니다.

  3. 이것은 팩토리 메소드의 예입니다. 지금은 단지 Builder의 인스턴스를 생성하고 반환하지만 나중에 인스턴스를 생성하고 반환하기 전에 인스턴스를 수정하거나 인스턴스를 반환하기 전에 보안 검사를 수행하도록 변경할 수 있습니다.

  4. 네, 맞습니다. 내부 클래스의 인스턴스를 만들고 그 외부 클래스의 인스턴스를 얻으려면 build 메서드를 사용합니다.

  5. 대개의 경우, 좋은 디자인과 좋은 효율성 사이에는 절충점이 있습니다. 그러나 이번에는 (두 클래스 모두 두 개의 변수 String을 포함하고 있기 때문에) 메모리 사용량이 두 배가 되더라도 실제 메모리 사용량은 그다지 크지 않습니다. (당신은 메모리가 부족 할 경우, JVM 인수를 전달하여 JVM 힙 공간을 변경할 수 있습니다.)

  6. 예, 할 수 있습니다,이 개 String 객체를 취하는 Person 클래스로이 같은 public 생성자입니다. 그것들이 동등한 경우 Builder의 인스턴스를 생성하여

  7. 한 캔 단위 테스트 이것은 확인 이름을 설정하기 위해 withFirstNamewithLastName 방법을 사용하고 그 복귀 Person 개체 게터 메소드를 호출 전달 된 값 (문자열 equals 메서드 사용).

  8. String 클래스의 메서드를 사용하여 인수가 전제 조건을 충족하는지 확인하고 그렇지 않은 경우 예외를 throw 할 수 있습니다.

  9. 당신은 소개 java.util.Objects 클래스에 도입 된 편리한 방법을 활용할 수 (나는 당신이 의미하는 것은 하나 때문에 기본 초기화의 경우 될 값에 대한 null.에 통과하는 경우이다 있으리라 믿고있어) Java 7, Objects.requireNonNull(). 인수를 전달하면 인수가 null이면 예외가 발생합니다. 그렇지 않으면, 인수를 리턴합니다.

+0

세부 설명을 부탁드립니다. 이 패턴을 이해하는 데 많은 도움이됩니다. – user2712937

+0

@ user2712937 제 답변과 마찬가지로? 공식 답변으로 수락하십시오! – gparyani