2010-07-14 1 views
2

정확히 어떻게 호출되는지 모르겠습니다 만, 호출 할 수있는 클래스를 어떻게 생성 할 수 있는지 궁금합니다. 하나의 호출에서 여러 메소드를 사용할 수 있습니다. 예를 들어, 안드로이드 클래스를 사용하지만, 정말 중요하지 않습니다, 당신은 한 번에 방법 '클래스의 모든를 호출 할 수 있습니다 :이 일할 수 있다고 생각 할 수foo.bar() .baz(). quux()


AlertDialog.Builder().setItem().setTitle().setPositiveButton().setCancelable() ...etc 

유일한 방법은 모든 방법 this을 반환하는 경우 ,하지만 그것은 문제를 일으키는 것처럼 보입니다. 어떻게 확신 할 수는 없지만 단지 그렇게 보이는 것 같습니다.

또한이 기술의 이름은 무엇입니까?

답변

7

이 기술은 method chaining라고하며, 상상 한대로 정확하게 작동합니다. void 대신에 this을 반환하는 함수가 있습니다.

+0

가장 적은 문자 수로 응답했습니다.]] – Falmarri

1

문제가 발생하지 않습니다. 이를 달성하기위한 표준 방법은 this입니다.

Java StringBuilder은 예입니다. (see source는)

여기에는 수업이 뒤에 fluent interface

1

아이디어는 this에 대한 참조를 반환 가지고 있다고한다. 간단한 예를 살펴 보자 :

class A{ 
    public A setStuffs(){ 
     return this; 
    } 
    public A setOtherStuffs(){ 
     return this; 
    } 
} 

그런 다음 당신이 할 수 있습니다

A a = new A().setStuffs().setOtherStuffs(); 

당신은 AlertDialog.Builder 같은 빌더 패턴을 사용하여 수업이 표시됩니다. 그러나 나는 보통 모든 클래스에서 코드 라인을 저장하는 데 도움이되기 때문에 그렇게한다.

2

이것은 작성자 패턴입니다.
당신이 효과적으로하고있는 것은 :

AlertDialog.Builder builder = new AlertDialog.Builder(ctx); 
builder.setIcon(android.R.drawable.icon); 
builder.setTitle(R.string.title); 
builder.setMessage(R.string.message); 
//etc. 
0

이이 방법 체인과 그 효과를 얻을 수있는 가장 쉬운 방법은 각 방법에서 개체의 현재 인스턴스를 반환하는 것입니다라고 ...

class MyCoolChainingObject{ 

    public MyCoolChainingObject doSomething(){ 
     //TODO: Stuff 
     return this; 
    } 

    public MyCoolChainingObject doSomethingElse(){ 
     //TODO: Stuff 
     return this; 
    } 
} 

....

1

나는 항상 이런 종류의 개체를 "빌더"라고 불렀습니다.

좋은 디자인은 작성중인 인스턴스를 반환하기 위해 마지막에 .build() 호출을하는 경향이 있습니다.

중간의 모든 메소드 호출은 빌더 객체를 반환합니다. 빌더 객체가 변경 가능하고 메소드 호출이 일부 내부 빌더 상태를 수정하는 경우 "this"가 될 수 있습니다. 또는 빌더 객체가 불변 인 경우 호출은 각각 완전히 새로운 불변 ​​빌더 객체를 반환 할 수 있습니다.

+0

ps 이런 API를 디자인한다면, 빌더 객체를 불변으로 만들 것을 권한다. 사용자가 빌더 객체를 전달하고 다른 스레드에서 사용하기 시작하면 장기적으로 큰 고통을 줄일 수있다. 이는 지속적인 데이터 구조를 위해 일부에 백업 데이터를 저장함으로써 매우 쉽게 수행 할 수 있습니다. – mikera

0

메서드 체이닝을 설명하는 모든 사람은이 기능을 구현하는 데 매우 합리적인 방법을 보여 주지만 함수가 무언가를 반환 할 필요가없는 경우에만 가능합니다. 뭔가를 돌려주고 싶다면?

(비록 좋지 않지만) 해결책은 함수를 호출하는 ReturnThis에 대한 부울 인수로 모든 메소드를 오버로드하여 반환하는 것입니다. 그러나 필자는이 대신에 빌더 패턴을 권장 할 것입니다.

OR! 실행할 함수를 비트 인수로 취하는 함수입니다. (ZOMG는 끔찍한 해결책입니다.)

OR STILL! C#을 사용하고 대리자 (함수 포인터)의 매개 변수 배열을 사용하고 배열을 반복하여 배열을 호출하여 모두 호출합니다 (심지어 더 심합니다!)

이러한 옵션 만 제공 할 수 있습니다. 메쏘드 체인을 할 수 없다면, 빌더로 가거나, 그것들을 모두 자신의 라인에서 호출하십시오. 또는 위의 세 가지 옵션 중 하나를 사용하십시오 (하지만이 단계에있는 경우 요구 사항의 유효성을 질문 할 수 있습니다). 또한

3

, 오히려 일반 자바 클래스와, 항상 반환 "이", 당신은 또한 단지 이중 중괄호 클래스 인스턴스 해킹을 사용할 수있는 클래스를 구축하는 것보다 :

AlertDialog.Builder(){{ 
    setItem(); 
    setTitle(); 
    setPositiveButton(); 
    setCancelable(); 
    ...etc 
}} 

여기에 좋은 참고가의 - http://www.c2.com/cgi/wiki?DoubleBraceInitialization

+0

그리고 마지막에'.create()'가 있습니다 :'AlertDialog dialog = AlertDialog.Builder() {{...}}. create();' –

+0

이중 중괄호 인스턴스화를 항상 테스트 코드로 사용합니다. 프로덕션 코드에서는 필자가 피할 때마다 새로운 클래스를 만드는 바람에이를 피한다. 이것은 내가 피하는 것을 선호하는 비용입니다. – RHSeeger

관련 문제