Java 7의 연결 호출?
-
06-07-2019 - |
문제
난 그냥 읽고 있었어 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는 많은 논증이있는 생성자가있을 때 빌더의 사용을 강력하게 권장합니다. 한 가지 이유는 내장 된 객체가 항상 일관된 상태에 있음을 보장하기 위해 기록 될 수 있기 때문입니다. 또한 내장 된 물체의 클래스에 복잡한 "텔레 스코핑 생성자"가 피하는 것을 피합니다. 또 다른 또 다른 것은 내장 된 객체를 불변 (예 : 스레드 안전을 위해)을 원한다면 세터 방법을 가질 수 없다는 것입니다.