callback

C#, .NET 2011. 6. 17. 19:21
callback 은 C#의 feature가 아니라, delegate 를 사용하는 하나의 pattern이다.

callback 은 하나의 객체가 자동적으로 다른 객체에 반응하도록 하여 두 클래스 사이의 관계를 확립하는 것이다.

callback은 정확하게 하나의 객체(에 속한 메쏘드)를 하나의 대리자에 연결하기 위해 사용된다.

(이벤트는 여러 메쏘드를 엮을 수 있으나 delegate 는 하나의 메쏘드만을 가리킬수 있다는 것을 이용)

이벤트와 콜백은 모두 대리자를 사용하므로 비슷해 보이지만

이벤트가 어떤 사건이 일어났음을 만천하에 알리는 개념인데 반하여 (이벤트를 발행)

콜백은 이벤트처럼 발행되는 것이 아니다.


예)
Class : Bat , Ball , 관중, 심판 

Bat가 HitTheBall event 를 발생시키면 

그것을 구독하는 Ball 이 BallInPlay 이벤트를 발생시키고

BallInPlay 이벤트를 구독하는 관중과 심판이 각자 나름의 동작을 한다.



위 구조 그대로 구현할 시 문제점이 한가지 있는데 

Ball 클래스의 생성자에서 Bat 객체를 받아서 자신의 메쏘드를 Bat 객체의 이벤트 헨들러로 등록한다고 해보자.

경기장에는 공이 1개만 있어야 하는데 실수로 Ball 객체를 여러개 만들었다면

Bat가 HitTheBall event를 발생시키면 여러개의 공들이 모두 반응하게 된다.



solution 1.
Ball 을 singleton 으로 만든다. ( 이게 짱인듯 ..)

solution 2.
callback을 사용하여 Bat에 어떤 특정 Ball 객체의 method 를 연결한다. (뭔가 설명을 위한 예제같지만..)


    public delegate void BatCallBack(EventArgs e);    

    public class Bat {
        //이벤트는 public 으로 해도 외부에서 직접 call이 불가능하나, 
      //delegate 는 그렇지 않으므로 get 을 private 으로 하였음        
        public BatCallBack HitBallCallBack { private get; set; } 
        public void HitTheBall(EventArgs e) { //물론 EventArgs 대신 다른걸 전달해도 됨
            HitBallCallBack(e);
        }
    }

    public class Ball {
        public event EventHandler BallInPlay;
        public Ball(Bat bat) {
            bat.HitBallCallBack = this.OnBallInPlay;
        }
        protected void OnBallInPlay(EventArgs e) {
            if(BallInPlay!=null)
                BallInPlay(this, e);
        }
    }



Bat bat = new Bat();
Ball ball = new Ball(bat);
bat.HitTheBall(new EventArgs());




<callback의 다른 사용 예>
두더지 잡기 게임을 만든다고 해보자.

각 구멍을 하나의 객체로 표현하면 되는데, 문제는 각 구멍을 나타내는 button 을 제어하는 것이다.

한가지 방법은 구멍을 나타내는 객체에 button 을 멤버로 넣는 것이 있고 (사실 제일 간단하고 좋아보인다)

두번째 방법은 callback 을 사용하는 것이다.

button을 제어하는 함수는 form 에 만들고 이 함수의 delegate 를 구멍객체에 전달하는 것이다.

보안상[?] 이게 더 나을것 같기도 하고.. 잘 모르겠다.


두더지 잡기 게임은 headfirst C# p554~555 에 나와있다.

'C#, .NET' 카테고리의 다른 글

ref 와 out  (0) 2011.06.17
유용한 클래스/스트럭트/메쏘드  (0) 2011.06.17
delegate  (0) 2011.06.17
event  (0) 2011.06.17
I/O 를 할 수 있는 각종 Stream Class 들, 자동 닫기, 객체 직렬화  (0) 2011.06.17
Posted by 휘사마
,