2012-12-19 3 views
6

부분을 이해하려는 시도입니다. 항목 40 : 설계 방법 서명 조심스럽게을 Effective Java 2 판에서.메서드 호출을위한 작성자 패턴 적용

메소드 시그니처 가독성을 향상시키기 위해 제안되는 것들 중 하나는 4 개 이하의 매개 변수를 목표로하는 것입니다. 이는 다음 중 하나는 다양한 기술을 사용하여 더 긴 파라미터리스트를 관리 할 수 ​​있다고 제안된다

제 두 측면 께 빌더 패턴을 적용하는 결합 세번째 방법 (항목 2)로부터 메소드 호출 에 대한 오브젝트 생성.매개 변수가 여러 개인 매개 변수가있는 메서드를 사용하는 경우 매개 변수 중 일부를 선택적으로 사용하는 개체를 정의하고 클라이언트가이 개체에 대해 여러 개의 "setter"호출을 호출하도록 허용하는 것이 좋습니다 각각은 단일 매개 변수 또는 작은 관련 그룹을 설정합니다. 원하는 매개 변수에 이 설정되면 클라이언트는 해당 매개 변수의 최종 유효성 검사를 으로 수행하고 실제 계산을 수행하는 개체의 "실행"메서드를 호출합니다.

개체 작성에 사용되는 작성자 패턴은 잘 알고 있지만 메서드 호출에 적용하는 방법을 올바르게 이해했는지는 확실하지 않습니다.
여호수아 블로흐의 조언의 나의 해석이 올바른

public class Space { 

    public static class Builder { 
     // Required parameters 
     private final int x; 
     private final int y; 
     private final int z; 

     // optional params 
     private long time = 0; 

     public Builder(int x, int y, int z) { 
      this.x = x; 
      this.y = y; 
      this.z = z; 
     } 

     public Builder time(long val) { 
      time = val; 
      return this; 
     } 

     public void move() { 
      if (x == 0 || y == 0 || z == 0) { 
       throw new IllegalArgumentException("Cannot move to the centre of the universe"); 
      } 

      // Do the actual work here 
     } 
    } 

// public void move(int x, int y, int z, long time) { 
//  // Do the work here 
// } 

    public static void main(String[] args) { 
     new Builder(1, 1, -1).time(1234).move(); 
    } 
} 

이다 (필자는 move 방법에 대한 메소드 호출을 개선하기 위해 시도) : 여기

내가 지금까지 가지고 무엇인가?

+0

아 나는 그렇게하려고했지만 내 마음이 미끄러웠다. 나는 자바 용 jsfiddle과 같은 것을 검색하려고했다. –

+1

완료. 고마워요! –

+0

나는 다음과 같은 것을 작성하는 것이 좋다고 생각한다 :'Builder builder = new MoveBuilder(). x (123) .y (456) .time (789); yourObject.execute (builder); ' – assylias

답변

1

내가했던 reifications : 유창 빌더 및 공장 방법을 사용하여.

이에 대한 추가 정보와 관련 "양방향 빌더"여기를 참조하십시오 : http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html?page=3

나는 다음과 같은 일을 할 것입니다; 이것은 아마도 3 개의 필수 입력란에 대한 잔인 함이지만 모든 필수 입력란을 고려하면서 큰 개체를 구성하는 데 매우 유용합니다.

public Class Space 
{  
    public interface Builder 
    { 
     public Space build(); 
     public int x(); 
     public int y(); 
     public int z(); 
    } 

    // Build a complete Space object accounting for every field. 
    public Space(Space.Builder spaceBuilder) 
    { 
     this.x = spaceBuilder.x(); 
     this.y = spaceBuilder.y(); 
     this.z = spaceBuilder.z(); 
     this.time = builder.time(); 
    } 

    // Might not be necessar if you update time when you update x, y, and z 
    public Builder time(long val) 
    { 
      time = val; 
      return this; 
    } 

    public void move() 
    { 
     // ... 
    } 

    public static void main(String[] args) 
    { 
     new Builder() 
     { 
      @Override 
      public Space build(){ return new Space(this);} 

      @Override 
      public int x(){ return 1;} 

      @Override 
      public int y{ return 1;} 

      @Override int z{ return -1;} 
     }.build().time(1234).move(); 
    } 
} 
2

내가 볼때, 당신은 당신의 빌더 클래스 (A 와 같은) 부모 클래스와 관련된 거라고 및 클라이언트는 다음과 같이 사용합니다 :

Space space = new Space(); 
... 
Space.MoveBuilder moveBuilder = space.new MoveBuilder(1, 1, -1); 
moveBuilder.setTime(1234); 
moveBuilder.execute(); 

그것은 추가로 단순화 할 수있다 내가 인스턴스화 할 클래스 내부에 정의 된 인터페이스를 사용하여 빌더 패턴의

space.startMove(1, 1, -1).withTime(1234).endMove(); 
+1

예, 저는 비 정적 클래스가 클래스와 그 둘러싸는 클래스 사이의 바인딩을 강조하는 것이 바람직하다는 데 동의합니다. –

0

Java Method Invocation Builder을 컴파일 할 때 메소드를 호출하는 빌더를 생성했습니다. 또한 Java의 메소드 매개 변수에 대한 기본값에 대한 지원을 추가합니다.

클래스 또는 인터페이스에서 사용할 수 있습니다. 유형에 @GenerateMethodInvocationBuilder@Default 주석을 추가하십시오.

BitBucketServerServicePullRequestsBuilder.pullRequests() 
.withAt("24") 
.invoke(bitBucketServerService); 

더에 : 당신이 원하는 매개 변수를

BitBucketServerServicePullRequestsBuilder.pullRequests() 
.invoke(bitBucketServerService); 

또는 설정 :

@GenerateMethodInvocationBuilder 
public interface BitBucketServerService { 
@GET("/rest/api/1.0/projects/{projectkey}/repos/{repositoryslug}/pull-requests?direction={direction}&at={at}&state={state}&order={order}&withattributes={withattributes}&withproperties={withproperties}") 
Call<BitbucketServerResponse<BitBucketServerPullRequest>> pullRequests(// 
    @Default("PROJ") @Query("projectkey") String projectKey,// 
    @Default("REPO") @Query("repositoryslug") String repositoryslug,// 
    @Default("INCOMING") @Query("direction") String direction,// 
    @Default("23") @Query("at") String at,// 
    @Default("OPEN") @Query("state") String state,// 
    @Default("NEWEST") @Query("order") String order,// 
    @Default("true") @Query("withattributes") String withattributes,// 
    @Default("true") @Query("withproperties") String withproperties); 
} 

다음 코드를 컴파일 할 때, 빌더가 생성되며 사용자는 기본 매개 변수를 호출 할 수 있습니다 GitHub : https://github.com/tomasbjerre/java-method-invocation-builder

관련 문제