C#과 Java언어 비교(3) - Event

C# and JAVA 2007. 5. 29. 10:49

원문 : http://genamics.com/developer/csharp_comparative_part4.htm

5. 이벤트

C# 직접적으로 이벤트를 지원한다. 비록 이벤트 처리가 프로그래밍이 시작된 이래로 프로그래밍에서 필수적인 부분이었다고는 하지만 대부분의 언어에서 이벤트의 개념을 정형화하고자 하는 노력은 놀랍게도 거의 없었다. 만약 여러분이 오늘날의 주류를 차지하는 프레임워크에서 이벤트를 처리하는 방식을 살펴보게 된다면 델파이(Delphi) 함수 포인터(클로져(closure) 불리는) Java 내부 클래스 어댑터, 그리고 물론 Windows API 메시지 시스템과 같은 선례를 찾을 있을 것이다. C# event 키워드와 함께 대리자(delegates) 이용하여 이벤트 처리에 있어 매우 깔끔한 해결책을 제시한다. 필자는 이를 보여주는 최선의 방법은 이벤트를 선언하고, 일으키고(fire), 처리하는 전체 과정을 보여주는 예제를 보여주는 것이라 생각한다:

// 호출될 있는 메소드의 서명을 정의하는 위임 선언

public delegate void ScoreChangeEventHandler (int newScore, ref bool cancel);

 

// 이벤트를 만드는 클래스

public class Game {

    // event 키워드를 사용하였음을 주목

    public event ScoreChangeEventHandler ScoreChange;

 

    int score;

 

        // Score 프로퍼티

    public int Score {

        get {

            return score;

            }

        set {

            if (score != value) {

                bool cancel = false;

                ScoreChange (value, ref cancel);

                if (! cancel)

                    score = value;

            }

        }

    }

}

 

// 이벤트를 처리하는 클래스

public class Referee

{

    public Referee (Game game) {

        // 게임에서 점수가 언제 변하는 지를 관찰함

        game.ScoreChange += new ScoreChangeEventHandler (game_ScoreChange);

    }

 

    // 메소드의 서명이 ScoreChangeEventHandler 서명과 어떻게 일치하는지 주목하라

    private void game_ScoreChange (int newScore, ref bool cancel) {

        if (newScore < 100)

            System.Console.WriteLine ("Good Score");

        else {

            cancel = true;

            System.Console.WriteLine ("No Score can be that high!");

        }

    }

}

 

// 모든 것들을 테스트 하는 클래스

public class GameTest

{

    public static void Main () {

        Game game = new Game ();

        Referee referee = new Referee (game);

        game.Score = 70;

        game.Score = 110;

    }

}

GameTest에서는 게임을 하나 만들고, 게임을 관찰하는 참조변수를 하나 만든 다음, 참조 대상이 게임 점수가 변경되었을 어떻게 반응하는지를 확인해 보기 위하여 게임 점수를 변경한다. 시스템에서 Game 참조변수에 대해 아무것도 알지 못하며, 그리고 아무 클래스나 점수가 변경되는 것을 감시하고 변화에 대응하도록 해준다. event 키워드는 모든 대리자의 메소드를 += -=과는 상관없이 그것이 선언되어 있는 클래스가 아닌 클래스로 숨긴다. 이러한 연산자는 여러분이 원하는 만큼 여러 개의 이벤트 처리기를 이벤트에 추가하거나 제거할 있도록 해준다.


여러분은
아마도 GUI 프레임워크에서 이러한 시스템을 처음 접하게 될텐데, Game 사용자 입력에 따라 이벤트를 일으키는 UI 위젯에 해당되며, 참조 대상은 이벤트를 처리하게 폼에 해당될 것이다.


대리자는
Microsoft J++에서 처음으로 도입되었으며, 또한 Anders Hejlsberg 의해 설계되었고 Sun Microsoft간의 수많은 기술적, 법적 분쟁을 야기시켰다. Java 설계했던 James Gosling Anders Hejlsberg 관해 그의 델파이에 대한 애착이 그를 메소드 포인터씨(Mr. Method Pointers)” 만들었다라고 말하면서 농담을 건넸다. Sun에서 만들어진 대리자에 관한 논쟁을 검토한 후로 필자는 Gosling “’모든 것은 클래스다 부르는 것이 공평하다고 생각한다. 지난 년간의 프로그래밍은 현실을 모델링하기 위해 추상화하는 으로부터 많은 사람들에 의해 현실은 객체지향이며, 따라서 우리는 객체지향적인 추상화를 통해 모델링해야만 한다 바뀌었다.

대리자에 관한 Sun Microsoft 논쟁은 아래에서 찾아볼 있다:

: