문제

Java 언어의 기능을 위임과 비슷한 방법 C#을 지원한 대리인?

도움이 되었습니까?

해결책

지 않는 정말 아니다.

할 수 있는 것과 같은 효과를 얻을 사용하여 반영을 얻는 방법 개체할 수 있음 호출,다른 방법은 인터페이스를 만들어 하나의'호출'또는'실행'방법,그리고 다음을 인스턴스화들을 메소드를 호출하에 관심을(즉를 사용하는 익명의 내부 클래스).

수도 있습니다 이 문서에서 흥미로운/유용합니다: Java 프로그래머에서 보이는 C#대리

다른 팁

따라 정확하게 당신이 무엇을 의미할 수 있습 유사한 효과를 달성(주위에 전달방법)을 이용하여 전략 패턴이다.

대신 다음과 같은 줄을 선언하라는 방법인 서명:

// C#
public delegate void SomeFunction();

인터페이스를 선언:

// Java
public interface ISomeBehaviour {
   void SomeFunction();
}

콘크리트를 위한 구현 방법의 정의를 클래스를 구현하는 행동:

// Java
public class TypeABehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeA behaviour
   }
}

public class TypeBBehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeB behaviour
   }
}

그때 어디든지 당신이 했 SomeFunction 대 C#에서 사용 ISomeBehaviour 참조 대신:

// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();

// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();

익명의 내부 클래스,수도 있습을 선언해서는 별도의 이름 클래스고 거의 치료를 그들을 실제와 같은 대리인 기능입니다.

// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
   ...
}

...

SomeMethod(new ISomeBehaviour() { 
   @Override
   public void SomeFunction() {
      // your implementation
   }
});

이게만 사용될 때는 구현이 매우 특정을 현재의 컨텍스트와 이용할 수 없게 되에서 재사용 가능합니다.

다음의 과정에서 Java8,이렇게 되는 기본적으로 람다 식:

// Java 8
SomeMethod(() -> { /* your implementation */ });

짧은 이야기:no.

소개

최신 버전의 Microsoft Visual J++개발 환경 을 지원하는 언어를 구축 라 바인딩 방법 references.이 구조물,그리고 새로운 키워드 delegatemulticast 도입을 지원하는,그것의 일부가 아닙니다 JavaTM 프로그래밍 언어로 지정 Java 언어 사양 과에 의해 개정 내부 클래스 사양 포함 에 에 대한 설명서를 JDKTM1.1 소프트웨어.

그것은 가능성이 있는 Java 프로그래밍 언어 이제까지 포함 이 구조물이다.태양 이미 신중하게 고려 채택하는 그는 1996 년에, 하는 범위 내의 건물과 폐기를 작동 프로토타입을 제작할 수 있습니다.리 결론이었는 바인딩 방법을 참조은 불필요하고 유해하는 언어입니다.이 결정되었에서 상담 Borland 국제했던 이전의 경험을 바 방법 참조 델파이 Object Pascal.

우리가 믿는 바인딩 방법을 참조가 기 때문에 다른 디자인 대체 내부 클래스, 제공 동등 또는 우수한 기능입니다.특히,내부 클래스를 완벽하게 지원 요구 사항의 사용자 인터페이스에 이벤트 처리,사용되어왔기 을 구현하고 사용자 인터페이스 API 에서 이상으로 포괄적으로 윈도우 기본 클래스입니다.

우리가 믿는 바인딩 방법을 참조가 유해 기 때문에 그들은 떨어 에서 단순함의 자바 프로그래밍 언어 퍼지 개체 지향적인 성격의 일으킬 수 있습니다.바인딩 방법 참조 또한 소개하는 불규칙으로 구문 및 언어 범위 지정 규칙이 있습니다.마지막으로,그들은 희석에 대한 투자 VM 기술 기 때문에 Vm 은 처리하는 데 필요한 추가하고 서로 다른 종류의 참조 방법을 결합을 효율적으로 합니다.

당신은 읽 :

에 대한 유용한 구조에서의 이벤트 기반 시스템입니다.기본적으로 대표단은 개체를 인코딩하는 방법을 파견서에 지정 체입니다.이 문서는 방법을 보여 줍니다 java 내부 클래스 제공 일반적인 솔루션을 같은 문제를 준비하고 있습니다.

무엇 대리인?정말 그것과 매우 유사하다는 포인터를원 함수에서 사용하는 C++.그러나 대리인을 포함 대체 alongwith 이 메소드를 호출합니다.이것은 좋을 것이다 고 말할 수 있:

obj.registerHandler(ano.methodOne);

고 그 방법 methodOne 것에 ano 때 어떤 특정 이벤트가를 받았습니다.

이 대리인 구조를 달성한다.

내부 클래스 Java

그것을 주장하고있는 자바를 제공합이 기능을 통해 익명의 내부 클래스고,따라서 필요로하지 않 추가 대리자를 구성.

obj.registerHandler(new Handler() {
        public void handleIt(Event ev) {
            methodOne(ev);
        }
      } );

처음에는 눈이 올바른 것 같지만 동시에 사용자를 귀찮게 합니다.기 때문에 많은 이벤트 처리를 예제는 단순함의 대표 구문은 매우 매력적이다.

일반적인 핸들러

그러나,경우 이벤트 기반 프로그래밍에 사용되는 더 점진적인 방식으로,예를 들어,예를 들어,일부로서의 일반 비동기 프로그램은 환경,거기에 더 많은 것이 걸려있다.

에서 이러한 일반적인 상황으로 충분하지 않을 때만 포함 대상 및 방법 대상 객체를 인스턴스입니다.일반적으로 거의 수 기타 필요한 매개 변수 결정하는 컨텍스트 내에서 때 이벤트 처리기로 등록합니다.

에서 이보다 일반적인 상황,java 접근 방식을 제공할 수 있는 아주 우아한 솔루션,특히 때와 결합의 사용은 최종 변수:

void processState(final T1 p1, final T2 dispatch) { 
  final int a1 = someCalculation();

  m_obj.registerHandler(new Handler() {
    public void handleIt(Event ev) {
     dispatch.methodOne(a1, ev, p1);
    }
  } );
}

최종*최종*최종

관심있으세요?

참고 최종 변수 내에서 액세스할 수 있는 익명 클래스 메소드를 정의 합니다.야를 연구한 이 코드를 주의깊게 문제를 이해해.이것은 잠재적으로 매우 강력 기술입니다.예를 들어,그것은 사용할 수 있습니다 좋은 효과를 경우 등록 에서 처리기 MiniDOM 과에서 보다 일반적인 상황입니다.

대조적으로,대리인을 구성하지 않습에 대한 솔루션을 제공 이상,일반적인 요구와 같은 거부되어야로 관용구에서는 디자인을 기반 할 수 있습니다.

이 게시물은 오래된하지만,Java8 는 추가 람다,의 개념 및 기능적 인터페이스는 모든 인터페이스를 하나의 방법입니다.함께 이러한 이와 비슷한 기능을 제공하는 C#습니다.여기에 참조에 대한 자세한 정보,또는 다만 구글 자바 람다.http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

아니,그러나 그들은 fakeable 프록시를 사용하 및 반사:

  public static class TestClass {
      public String knockKnock() {
          return "who's there?";
      }
  }

  private final TestClass testInstance = new TestClass();

  @Test public void
  can_delegate_a_single_method_interface_to_an_instance() throws Exception {
      Delegator<TestClass, Callable<String>> knockKnockDelegator = Delegator.ofMethod("knockKnock")
                                                                   .of(TestClass.class)
                                                                   .to(Callable.class);
      Callable<String> callable = knockKnockDelegator.delegateTo(testInstance);
      assertThat(callable.call(), is("who's there?"));
  }

에 대 한 좋은 것은 이 문구가할 수 있는지 확인하는 위임하는 방법이 존재하고 필요한 서명 시점에서,당신은 만들기 위임자(지 않지만에 컴파일 시간도 있지만,FindBugs 플러그인에 도움이 될 수 있습 여기서),다음을 안전하게 사용하는 위임하는 다양한 인스턴스가 있습니다.

karg 코드에 github 에 대한 더 많 테스트구현.

내가 구현한 콜백/대표에서 Java 를 사용하여 반영합니다.상세정보 및 작동 원 웹 사이트에서 사용 가능한.

그것이 어떻게 작동

거기에는 원칙적으 라는 이름의 클래스 콜백과 중첩된 라는 이름의 클래스 WithParms.API 에는 필요한 콜백을 콜백 개체 매개 변수로,필요한 경우를 만들 콜백입니다.WithParms 방법으로 변수입니다.기 때문에 많은 응용 프로그램의 이 객체의 것 재귀,이 작품을 매우 깨끗하게.

성능 여전히 우선 순위가 높은 나에게 나가고 싶지 않았을 것을 만들기 위해 필요한 일회용 개체 배열을 잡고 매개변수를 위해 모든 호출 후에서 모두 큰 데이터 구조에 있는 수 수천의 요소,그리고 메시지를 처리하는 시나리오를 우리가 끝날 수 있었 처리 수천의 데이터 구조다.

하기 위해서는 영역에서 매개 변수 배열의 요구를 존재에 대해 유일하게 각 호출의 API 를 방법,그리고 효율성에 대한 동일한 하나의 사용해야 하는 모든 콜백을 호출;필요 두 번째는 개체는 것 만들에 바인딩하기 위해 콜백을 매개 변수 배열에 대한 호출을 기반으로 합니다.지만,일부 시나리오에서 호출자가 이미 매개 변수 배열에 대한 다른 이유가 있습니다.이러한 두 가지 이유로,매개 변수 배열에 속하지 않는 콜백체입니다.또한 선택 호출(전달하는 매개변수를 배열로 또는 개별적 개체)그리고 손에서의 API 를 사용하여 콜백을 사용하에 그것을 사용하여 어느 호출에 가장 적합한 내부 동작.

이 WithParms 중첩된 클래스를 다음 선택 사항하고는 두 가지 목적으로,그것은 매개 변수를 포함한 개체 배열에 필요한 콜백을 호출,그리고 제 10 버 invoke()메소드(으로 1 에서 10 매개 변수)는 부하를 매개 변수 배열한 다음 콜백을 호출 대상입니다.

다음은 예를 들어를 사용하여 콜백하는 프로세스에서 파일이 디렉토리 나무입니다.이것은 초기 검증을 통과하는 그냥 카운트한 파일을 프로세스가 없는지 확인을 초과하는 소정의 최대 크기입니다.이 경우에 우리는 그냥 만들 콜백과 인라인 API 를 호출을 기반으로 합니다.그러나 우리는 목표를 반영 방법으로 정적 가치도록 반사 수행되지 않습니다.

static private final Method             COUNT =Callback.getMethod(Xxx.class,"callback_count",true,File.class,File.class);

...

IoUtil.processDirectory(root,new Callback(this,COUNT),selector);

...

private void callback_count(File dir, File fil) {
    if(fil!=null) {                                                                             // file is null for processing a directory
        fileTotal++;
        if(fil.length()>fileSizeLimit) {
            throw new Abort("Failed","File size exceeds maximum of "+TextUtil.formatNumber(fileSizeLimit)+" bytes: "+fil);
            }
        }
    progress("Counting",dir,fileTotal);
    }

IoUtil.processDirectory():

/**
 * Process a directory using callbacks.  To interrupt, the callback must throw an (unchecked) exception.
 * Subdirectories are processed only if the selector is null or selects the directories, and are done
 * after the files in any given directory.  When the callback is invoked for a directory, the file
 * argument is null;
 * <p>
 * The callback signature is:
 * <pre>    void callback(File dir, File ent);</pre>
 * <p>
 * @return          The number of files processed.
 */
static public int processDirectory(File dir, Callback cbk, FileSelector sel) {
    return _processDirectory(dir,new Callback.WithParms(cbk,2),sel);
    }

static private int _processDirectory(File dir, Callback.WithParms cbk, FileSelector sel) {
    int                                 cnt=0;

    if(!dir.isDirectory()) {
        if(sel==null || sel.accept(dir)) { cbk.invoke(dir.getParent(),dir); cnt++; }
        }
    else {
        cbk.invoke(dir,(Object[])null);

        File[] lst=(sel==null ? dir.listFiles() : dir.listFiles(sel));
        if(lst!=null) {
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(!ent.isDirectory()) {
                    cbk.invoke(dir,ent);
                    lst[xa]=null;
                    cnt++;
                    }
                }
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(ent!=null) { cnt+=_processDirectory(ent,cbk,sel); }
                }
            }
        }
    return cnt;
    }

이 예제는 아름다움을 이 방법의 응용 프로그램-특정 논리로 추상화되 콜백과 단조롭고 재귀적으로 걷는 디렉토리에서 자리 잡고 멋지게 멀리에서 재사용할 수 있는 정적 유틸리티는 방법입니다.우리는 없다를 반복적으로 가격을 지불을 정의하고 구현하기 위한 인터페이스마다 새로운 사용.물론,인수 인터페이스는 훨씬 더 많은 명시적에 대해 무엇을 구현하는(그것의 적용,간단하게 문서화되)-그러나 실제로는 발견하지 않았습니다 그것이 문제가 될 수를 얻을 콜백을 정의 옳습니다.

을 정의하고 구현하는 인터페이스는 정말 그렇게 나쁜(지 않는 한 당신이 배포하는 애플릿으로,나는,어디를 피하고 만들기 여분의 수업은 실제로 상당히 중요합니다)하지만 어디에이 정말 빛나는 여러 개 있는 경우 콜백에서 하나의 클래스입니다.뿐만 아니라 강제로 밀어들을 서로 별도의 내부 클래스에 추가의 오버헤드에서 배포된 응용 프로그램이지만,그것은 명백히 지루한 프로그램과는 모든 보일러 플레이트 코드는 정말 그냥"노이즈".

는 동안 그것은 아무데도 거의 같은 깨끗하지만,구현할 수 있는 뭔가가 다음과 같 C#대리자를 사용하여 Java 프록시.

아니,하지만 그것은 유사한 문제,내부적으로 합니다.

C#에서 대리인 사용을 생성하는 별도의 항목이 포인트 및 그들은 작업과 같은 많은 함수 포인터이다.

에서 자바가 없는 것으로 함수 포인터(에 위쪽 보기)그러나 내부적으로 자바의 요구 같은 일을 하기 위해서 그리고 이러한 목표를 달성하기 위해.

예를 들어,만드는 스레드에서 Java 필요한 클래스를 확장 스레드 또는 구현하는 실행 가능한 때문에 클래스 개체 변수를 사용할 수 있는 메모리 위치로 포인터이다.

예 아니,그러나 위임 패턴 자바에서 생각할 수 있습의 이 방법입니다. 이 비디오 자습서 에 대해 데이터 교환이 활동 조각,그리고 그것은 본질의 대리자는 그 패턴을 사용하여 인터페이스가 있습니다.

Java Interface

Java 없는 대표와의 자랑입니다:).에서 무엇을 읽고 나는 여기에서 찾을 본질은 2 가지 방법으로 가짜 대리인:1.반사;2.내부 클래스

반사 slooooow!내부 클래스 커버하지 않는 가장 간단한 응용 사례:정렬 기능입니다.고 싶지 않은 세부 사항으로 이동,하지만 솔루션으로 내부 클래스는 기본적으로 래퍼를 만들어 클래스를 위해 정수 배열을 오름차순으로 정렬되고 있는 클래스를 위해 정수 배열을 내림차순으로 정렬됩니다.

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