함수 포인터 없이 인터페이스 외에 Java에서 콜백을 구현하는 데 권장되는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/626669

  •  06-07-2019
  •  | 
  •  

문제

서로에게 일부 정보를 전달하고 나중에 해당 정보(콜백 패턴)를 사용하여 다시 호출되기를 원하는 두 개의 클래스가 있습니다.

내 애플리케이션 내에서 이 메커니즘은 두 가지 목적으로 사용됩니다.

  • 예약/지연된 실행
  • 메시징을 포함하는 비동기 실행

내 개체는 기본적으로 서로에게 말합니다. "X 작업이 끝나면 다시 전화해서 Z와 함께 Y를 하라고 전해 주세요. (그때쯤이면 잊어버릴 테니까요)".X는 적절한 시간을 기다리고 있을 뿐만 아니라 원격 서비스와 통신하거나 로컬 기능을 호출할 수도 있습니다.

이제 Java에 함수 포인터(또는 이와 동등한 것)가 있었다면 필요한 인수와 함께 하나를 포함하는 "Job" 클래스를 구현했을 것입니다.예를 들어, PHP에서 이 구조는 클래스 이름, 함수 이름 및 인수 배열을 저장해야 합니다.C에서는 함수에 대한 포인터가 되며 모든 호출에 대해 인수를 동일한 수와 유형으로 만들어야 합니다.

Java에서 일반적인 접근 방식은 다음과 같이 콜백하려는 모든 클래스에 의해 구현되는 인터페이스를 갖는 것입니다.

public interface ICallable {
    public void call_me(Object data);
}

이제 이것은 나에게 효과가 없을 것입니다. 왜냐하면

  • 콜백될 객체에는 호출을 받기 위한 다른 메소드 세트가 있을 수 있습니다.
  • 발신자는 어떤 전화를 걸어야 할지 결정하는 사람이 아닙니다.

어쩌면 내 문제는 다양한 콜백에 대한 공통 데이터 구조와 호출 절차를 가지려고 한다는 것이지만 원칙적으로는 그것이 나에게 의미가 있는 것 같습니다.

Java에서 이러한 상황에 접근하기 위한 좋은 디자인 패턴은 무엇입니까?

도움이 되었습니까?

해결책

인터페이스가 최상의 솔루션이라고 생각합니다. 나는 그들에 대한 당신의 이의를 이해하지 못합니다. 수신기에 다른 메소드가 호출되어야하는 경우 인터페이스 메소드가 다른 메소드를 호출하도록하십시오.

수신기 클래스에 여러 핸들러가 있어야하는 경우 인터페이스를 구현하는 익명의 내부 클래스를 사용할 수 있습니다. 예를 들어, 발신자가 "ListenerInterface"라는 인터페이스를 사용하는 경우 수신기는 ListerInterface를 구현하고 수신기 메소드를 "handlerFunction"이라고 호출하는 익명의 내부 클래스를 정의 할 수 있습니다.

   sender.addListener(new ListenerInterface()
   {
      public void callback(Object arg)
      {
         handlerFunction(arg);
      }
   });

다른 팁

당신은 비슷한 개념을 사용할 수 있습니다 익명의 내부 수업

또 다른 참조 여기

설명대로 인터페이스를 사용한 다음 콜백에 익명 클래스를 사용합니다. 예를 들어 발신자 내부에서 :

ICallback callback = new ICallback() { 
    public void call_me(Object data) { this.actionToCall(data); }
}
serverObject.doX(callback);

(구문은 그것과 약간 다를 수 있습니다.)

이렇게하면 완료 될 때 취해야 할 동작 (통화 시점)에 원래 발신자 (통화 시점)를 지정할 수 있습니다.

당신이 정말로 인터페이스를 사용하고 싶지 않다면 (그리고 나를 믿으십시오!) 반사를 사용하여 호출하려는 메소드를 얻은 다음 전화를 걸어야하는 방법으로 전달할 수 있습니다. 이것은 당신이 얻을만큼 C 함수 포인터에 가깝습니다.

반사는 인터페이스 방식보다 느리게 (아마도) (아마도 자주 호출되지 않는 한 중요하지 않음).

반사에는 컴파일 타임 유형을 수행하는 방식이 수행하는 방식이 확인되지 않습니다 (런타임에 충돌 할 수 있음).

반사는 인터페이스 방식보다 추악한 코드가 될 것입니다.

그러나 정말로 실제로 C 함수 포인터를 시뮬레이션하고 싶다면 반사는 당신이 얻을만큼 가깝습니다.

콜백은 일반적인 아이디어이며 한 크기의 인터페이스를 시도해서는 안됩니다. 콜백 인터페이스를 사용에만 해당하십시오. 전달 된 유형의 의미와 일치하고 호출을 다시 수행해야합니다. 콜백 인터페이스의 일반적인 구현은 익명의 내부 클래스로 수행됩니다. 외부 클래스에서 인터페이스를 구현하려는 유혹에 저항하여 일관성이없는 유형을 만듭니다.

나는 문제를 오해하고 있을지 모르지만, 당신은 일종의 이벤트 시스템을 설정하는 것이 도움이 될 것 같습니다.

기본적으로 이벤트 핸들러와 이벤트 핸들러에 대해 알고 싶은 클래스를 설정합니다. 따라서 문제의 경우 X가 완료되면 객체가 구독 할 완료 처리 이벤트 ()를 발사합니다. 객체 가이 이벤트를 받으면 (이벤트에 관심이있는 다른 가입자와 함께) 적절한 조치 (y z)를 수행합니다. 이러한 동작은 객체 내에서 정의되므로 다른 객체는 동일한 이벤트에 따라 다른 일을 할 수 있습니다.

이것이 도움이됩니까?

귀하의 문제를 해결하는 몇 가지 흥미로운 패턴이 있다고 확신하지만 저는 인프라를 사용하는 단순한 접근 방식을 선택하겠습니다.JMS와 같이 메시지 대기열에 요청과 응답을 넣으면 시스템 재시작, 지속성 및 메시지 무결성에 대한 걱정 없이 몇 초 또는 몇 주가 소요되는 이벤트를 처리할 수 있으므로 시스템이 더 간단하고 강력해질 수 있습니다.

나는 그것에 너무 많이 보지 않았지만 Java 5+ 미래 인터페이스 (또는 하위 인터페이스)는 이에 유용 할 수 있습니다.

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