문제

난 그냥 읽고 있었어 Java 7 미리보기 프레젠테이션(pdf) 그리고 미끄럼틀이 있었어 연쇄 호출.슬라이드에 사용된 예는 다음과 같습니다.

// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();

// Construction with chained invocation
Drink margarita = new DrinkBuilder()
    .add("tequila")
    .add("orange liqueur")
    .add("lime juice")
    .withRocks()
    .withSalt()
    .drink();

그리고 나는 이것에 대해 엇갈린 감정을 가지고 있습니다.하나의 명령문에 너무 많은 메서드 호출을 연결하면 안 됩니다.반면에 글쓰기 margarita.this() 그리고 margarita.that() 너무 편리하지도 않습니다.

이제 저는 Delphi 세계에서 Java로 왔습니다.그리고 델파이에는 with 언어 구조.이것은 소수의 사람들이 소중히 여기고 많은 사람들이 혐오하는 것입니다(아니면 그 반대입니까?).내가 찾은 with 연쇄 호출 아이디어보다 더 우아합니다. void 호출된 객체에 대한 참조를 반환하는 메소드 - 이것은 제가 좋아하지 않는 부분입니다. void 반환해야 아무것도 아님).

나는 감사하겠습니다 with Java에서 언어 기능을 채택하고 있으므로 예제 코드는 다음과 같이 작성될 수 있습니다.

Drink margarita = null;
with (new DrinkBuilder()) {
    add("tequila");
    add("orange liqueur");
    add("lime juice");
    withRocks();
    withSalt();
    margarita = drink();
}

체인 호출보다 이 솔루션을 선호하는 사람은 나뿐인가요?다른 사람도 그렇게 느끼거든 with Java 언어에 대한 유용한 확장이 될 수 있습니까?("Java++"의 필요성에 대한 누군가의 질문이 생각나네요...)

도움이 되었습니까?

해결책

그만큼 ~와 함께 명령문은 초기에 익명 클래스를 사용하여 Java에서 번역 될 수 있습니다.

Drink margarita = new DrinkBuilder() {{
    add(“tequila”);
    add(“orange liqueur”);
    add(“lime juice”);
    withRocks();
    withSalt();
}}.drink();

이 관용구를 사용하는 단점은 잘 문서화되어 있습니다 여기.

체인 호출은 방법 체인의 별칭입니다. 그것은 잘 알려진 관용구이며 모든 버전의 Java와 함께 작동합니다.

class Chained {

    public Chained withFoo() { 
        // ...
        return this;
    }

    public Chained withBar() { 
        // ...
        return this;
    }
}    

JDK 7에 대한 제안은입니다 무효 리턴 유형에 대한 체인 방법 허용:

class ChainedJava7 {

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

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

다른 팁

이것 당신에게 관심을 가질 수 있습니다.

나는 굉장히 좋아한다 with 해당 형식의 설명을 사용하지만 저는 VB 버전을 선호합니다.

With testObject
    .Height = 100
    .Text = "Hello, World"
    .ForeColor = System.Drawing.Color.Green
End With

각 속성에 따라 With 블록 앞에는 여전히 . 로컬 변수가 아닌 Object 속성을 참조하고 있으므로 네임스페이스 충돌이 줄어듭니다.

귀하의 예를 들면 다음과 같습니다.

with (new DrinkBuilder()) {
    add(“tequila”);
    add(“orange liqueur”);
    add(“lime juice”);
    withRocks();
    withSalt();
    margarita = drink();
}

있는지 알 수 있는 쉬운 방법은 없습니다. withSalt() 의 방법이다 DrinkBuilder 또는 로컬 클래스의 메소드.다음의 메소드만 허용하는 경우 with-ed 개체 with 차단하면 훨씬 덜 유용해질 것 같아요.

나는이 사용의 팬이 아닙니다 with; 나는 더 선호한다 파이썬 with 성명. 나는 당신에게 동의합니다 void 의미가 있어야합니다 void, 그렇지만. 당신이 제공하는 예에서, 사람이 실제로 메소드 호출을 체인 할 수 있기를 원한다면, 메소드에서 반환 유형을 변경하여 체인이 가능합니다.

어쩌면 하나의 개체에 대한 많은 사람들이 일부 코드를 이동해야한다는 신호일까요?

조슈아 블로 치 효과적인 자바 항목 #2는 많은 논증이있는 생성자가있을 때 빌더의 사용을 강력하게 권장합니다. 한 가지 이유는 내장 된 객체가 항상 일관된 상태에 있음을 보장하기 위해 기록 될 수 있기 때문입니다. 또한 내장 된 물체의 클래스에 복잡한 "텔레 스코핑 생성자"가 피하는 것을 피합니다. 또 다른 또 다른 것은 내장 된 객체를 불변 (예 : 스레드 안전을 위해)을 원한다면 세터 방법을 가질 수 없다는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top