태양김민호의 금태양블로그

닷넷 클래스, 델리게이트, 이벤트 본문

SOFTWARE

닷넷 클래스, 델리게이트, 이벤트

金太陽 2013. 10. 16. 00:30

이번에는 우리가 가지고 있는 객체와 클래스의 기초 지식을 바탕으로 가상 모델링 해보도록 하겠습니다. 가상 모델링으로 구축 할 시스템은 바로 가상 축구 게임 입니다. 이제부터 클래스를 정의하고 동작(메서드)을 정의하는 요령을 익혀 보도록 합시다.

 

1. 일단 게임에 필요한 대상이나 동작 같은 요소들을 모두 적습니다.

사람, 공격수, , 패스, 골키퍼, 펀칭, 태클, 축구공, 전반전, , 선수, 수비수, 심판, 파울, 경기시간, 후반전 등등


2. 적어 놓은 요소들 중에는 동사와 명사가 있습니다. 명사는 바로 클래스가 되는 것이고 동사는 바로 메서드가 되는 것입니다. 이제 클래스와 메서드를 구분해 봅시다.
 

클래스(명사) - 사람, 공격수, 골키퍼, 축구공, 전반전, , 선수, 수비수, 심판, 경기시간, 후반전 등등

메서드(동사) - , 패스, 펀칭, 태클 등등

 

3. 다음은 클래스 안의 메서드를 정리 합니다.

 

4. 설계 된 클래스들의 연관을 살펴 보고, 상속과 추상 or 다형성의 개념을 도입합니다. 이번 단계는 앞서 우리가 공부한 객체 지향의 설계 방법을 활용할 수 있는 단계입니다.





처음 단순하게 늘어 놓았던 단어들이 한 단계, 한 단계 정리 되면서 제법 폼 있는 설계도가 완성 되었습니다. 클래스 모델링이라고 해서 절대 대단한 것이 있는 것이 아닙니다. 누구나 쉽게 설계하고 모델링 할 수 있습니다. 지금 언급한 4가지 단계는 필자의 필살기적 노하우를 정리 해 본 것입니다. 반드시 기억해 두시기 바랍니다.

우리가 게임이든 어떤 소프트웨어든 프로그래밍 하기 전에 가장 먼저 해야 할 중요한 작업이 클래스 모델링의 과정입니다. 체계적인 뼈대를 갖추고 프로그래밍을 하는 것과 뼈대를 세워 가면서 프로그래밍을 하는 것은 확연히 차이가 나게 됩니다.


앞서 말했듯이 객체 지향적 사고는 한번에 자신의 머리 속에 정착 되는 것은 아닙니다. 반드시 직접 설계해보고 토론해보고 또 생각해보는 반복적인 노력을 하시길 바랍니다. 그럼 어느새 내가 만든 프로그램은 뼈대가 생기게 될 것이고 더욱더 논리적인 프로그램을 만들 수 있을 것입니다.





 




 

델리게이트(delegate) 와 이벤트(Event)라는 녀석에 대해서 알아볼 것입니다. 델리게이트(delegate)와 이벤트(Event)는 우리가 여러 프로그램을 다루기 위해서는 반드시 알아 두어야 하는 필수 문법이므로 반드시 완벽한 이해를 가지고 넘어 가도록 합시다.


1. 델리게이트 (delegate)

델리게이트(delegate)의 사전적 의미로는 대리자 입니다. 대리자라는 사람은 무언가의 일을 대신해서 해주는 사람이라는 뜻입니다. 이와 같은 뜻으로 델리게이트 역시 프로그램에서 어떠한 기능을 대신 수행해 주는 역할을 가지고 있는 것입니다. 어려운 것이 아닙니다. 대신해서 수행 해 주는 녀석! 정도로 정의 해두고, 어떠한 일을 대신 해 주는 것인지를 같이 학습해 보겠습니다.

 

1.1 델리게이트(delegate)의 선언


델리게이트는 사용자정의형 이라고 정의 할 수 있습니다. 그렇다면 사용자 정의형 이라는뜻이 무엇인지 알아 봐야 될 것 같네요. 사용자 정의은절대 어려운 개념이 아닙니다. 사용자 정의형에 대표적인 예는 클래스(Class)입니다. 어떠한 특정 형식을 사용자가 정의 해 놓은 것을 의미 합니다. 아래 그림을 보고 이해 하도록 합시다.

 

[그림04-001]
델리게이트(delegate)사용자 정의형으로 클래스(Class)와 같은 위치에서 선언됩니다. 그리고 선언 형식은 메서드(함수)와 동일한 형식으로 선언됩니다. 눈치가 빠른 사람이라면 델리게이트(delegate)는 메서드와 연관이 있다라는 것을 짐작했을 것입니다. 그럼 델리게이트가 가지고 있는 기능을 살펴 보도록 하겠습니다.

 

2.2 메서드 대리자 델리게이트(delegate)
 

델리게이트의 대표적 기능은 메서드를 대신 수행해 주는 역할을 합니다. C언어에서는 포인터 함수라는 같은 개념이 존재합니다. 하지만 C#은 포인터의 개념을 사용하지 않으므로 이렇게 델리게이트라는 문법을 만들어 버린 것입니다. 솔직히 포인터 함수의 개념을 이해하고 배우는 것보다 델리게이트 문법을 익히는 것이 훨씬 쉽고 빠르게 이해 할 수 있습니다. 그만큼 차세대 언어는 개발자의 편의성을 많이 고려하여 설계 된 것입니다.
그럼 아래 예제를 통해서 델리게이트를 선언하는 방법과 어떻게 메서드의 대리자의 기능을 하게 되는지 살펴 보도록 합시다.
 

001: using System;

002: //델리게이트 선언

003: delegate void dele1();

004: delegate int dele2(int a,int b);

005: class MainClass

006: {

007:    static void Main(string[] args)

008:    {

009:           //Math클래스 선언및 인스턴스화

010:           MathClass MathClass=new MathClass();

011:           //델리게이트 선언및 인스턴스화

012:           dele1 Sum1=new dele1(MathClass.Intro);

013:           dele2 Sum2=new dele2(MathClass.Sum);

014:           //델리게이트에 위임된 메서드 실행

015:           Sum1();

016:           Console.WriteLine("Result : {0}",Sum2(-10,90));

017:    }

018: }

019: class MathClass

020: {

021:    public void Intro()

022:    {

023:           Console.WriteLine("계산을 시작합니다.");

024:    }

025:    public int Sum(int a, int b)

026:    {

027:           return a+b;

028:    }

029: }

결과

계산을 시작합니다.

Result : 80

 

먼저 MathClass를 만들었습니다. 이 클래스는 두 개의 메서드를 가지고 있습니다. 하나는 반환형과 매게변수가 없는 Intro 라는 함수 이고, 하나는 덧셈기능을 수행하여 리턴 해주는 Sum 이라는 함수입니다.

! 그럼 3~4번째 줄에 선언 된 델리게이트를 살펴봅시다. MathClass가 가지고 있는 함수와 똑같은 형식을 갖춘 델리게이트 두 개가 선언 되어 있습니다. dele1은 반환 값이나 매개변수가 존재하지 않고, dele2는 두 개의 int형 매개변수를 가지고 있으며 int 형 반환 값을 가지고 있습니다.

12,13번째 줄에 보면 선언된 델리게이트를 인스턴스화 시킵니다. 그리고 생성자에는 메서드가 참조 됩니다. 만약 dele1 Sum1=new dele1() 이렇게 델리게이트를 선언한다면 컴파일 에러가 발생하게 됩니다. , 델리게이트는 반드시 메서드를 참조 시켜야 한다는 사실을 반드시 기억하고 있어야 합니다.

그리고 만약 dele1 MathClass.Sum과 같은 매개변수와 선언 형식이 다른 메서드를 참조 시키려고 해도 "메서드와 대리자가 일치하지 않습니다" 라는 컴파일 에러가 발생 하게 되고 위임 메서드는 대리자와 형식이 일치 해야 된다는 사실 역시 기억해 두어야겠죠.

이제 15,16번째 줄에서 Sum1() Sum2라는 델리게이트를 실행하게 됩니다. 그럼 이제 위임 받은 메서드를 대신하여 실행 하게 되는 것입니다. 결과 역시 메서드를 직접 호출하는 것과 같은 값이 출력 됩니다.

 

2.3 델리게이트(delegate)의 연산
 

델리게이트 객체는 Combine Remove 라는 두개의 연산 메서드를 지원합니다. 이것은 델리게이트가 여러 메서드의 참조가 가능하다는 것입니다.

-Combine: 기존의 위임에 또 다른 위임을 추가합니다.           =[+]

-Remove: 기존의 위임에 특정 위임을 제거합니다.                 =[-]

그럼 이러한 연산 메서드가 어떻게 사용되는지 아래 예제를 통해서 연산되는 과정을 살펴 보도록 합시다.
 

001: using System;

002: delegate void deleMath(int Value); //델리게이트 선언

003: class MainClass

004: {

005:    static void Main(string[] args)

006:    {

007:           //Math클래스 선언및 인스턴스화

008:           MathClass MathClass=new MathClass();

009:          

010:           //델리게이트 선언및 인스턴스화(덧셈)

011:           deleMath Math=new deleMath(MathClass.Plus);

012:

013:           //위임연산(뺄셈,곱셈추가)

014:           Math+=new deleMath(MathClass.Minus);

015:           Math+=new deleMath(MathClass.Multiply);

016:           //결과1

017:           MathClass.Number=10;

018:           Math(10);

019:           Console.WriteLine("Result:{0}",MathClass.Number);

020:

021:           //위임연산(뺄셈제거)

022:           Math-=new deleMath(MathClass.Minus);

023:           //결과2

024:           MathClass.Number=10;

025:           Math(10);

026:           Console.WriteLine("Result:{0}",MathClass.Number);

027:

028:           //위임연산(곱셈제거)

029:           Math-=new deleMath(MathClass.Multiply);

030:           //결과3

031:           MathClass.Number=10;

032:           Math(10);

033:           Console.WriteLine("Result:{0}",MathClass.Number);

034:

035:    }

036: }

037: class MathClass

038: {

039:    public int Number;

040:    public void Plus(int Value)//더하기

041:    {

042:           Number+=Value;

043:    }

044:    public void Minus(int Value)//빼기

045:    {

046:           Number-=Value;

047:    }

048:    public void Multiply(int Value)//곱하기

049:    {

050:           Number*=Value;

051:    }

052: }

 

결과

Result:100

Result:200

Result:20

 

37번째 줄에 정의 된 MathClass의 메서드들을 살펴 보면 3개의 연산 메서드들이 존재합니다. 이 메서드들은 매개변수로 받은 값을 Number라는 전역변수와 연산을 하고 Number 변수에을 저장하게 됩니다.

먼저 += 연산자의 의미를 살펴 보도록 합시다. 만약 int i =5;라고 선언을 하고 i 10을 더해주고 싶다면 i+=10; 이렇게 코딩을 하여 사용해 왔을 것입니다. i+=10; i=i+10과 같은 뜻이 됩니다. 여기서 사용된 += 연산자 역시 마찬가지 의미로 사용 됩니다. 단지 여기는 메서드를 추가로 참조 시키고 뺀다는 의미가 되는 것입니다.

그럼 코드의 11번째 줄을 살펴 봅시다. Math 델리게이트는 선언함과 동시에 Plus 메서드를 기본으로 참조 시켰습니다. 그리고 14번째 줄을 보면 += 연산을 이용하여 추가로 메서드를 추가하고 있습니다. 이제 Math 델리게이트는 3개의 메서드가 참조된 델리게이트가 된 것입니다. 18번 줄 에서는 10이라는 매개 변수를 넣어 델리게이트를 실행합니다. 이 데릴게이트는 Plus(10),Minus(10),Multiply(10) 이렇게 세 개의 메서드를 차례대로 호출하는 것과 똑같은 의미를 가집니다. 결과 역시 차례대로 수행한 100이 출력됩니다.

이제 22번째 줄을 봅시다. - 연산자를 이용하여서 메서드를 Minus메서드를 참조에서 제외시킵니다. 처리 결과를 출력해 보면 곱하기와 덧셈 메서드만 실행된 화면을 볼 수 있습니다.

위에서 살펴본 것 과 같이 +=, -= 와 같은 연산자를 이용하여서 여러 메서드들을 추가 하고 참조를 제어 할 수 있다는 것을 알 수 있을 것입니다.

 

델리게이트는 나중에 다루어질 스레드, 비동기 처리, 이벤트 등등에서 기본으로 사용 되는 아주 중요한 문법입니다. 델리게이트를 선언하고, 메서드를 참조하여 사용 하는 방법까지 확실하게 이해하고 넘어 가길 바랍니다.

 

 

2. 이벤트 (Event)

 

앞서 학습한 델리게이트를 활용하기 위해서 이벤트라는 녀석을 학습해 보도록 하겠습니다. 윈도우 프로그램을 다루어 보신 분이라면, 쉽게 이해할 수 있을 것이지만, 윈도우 응용프로그램을 다루어 본적이 없으신 분이라면 ! 이벤트?! 그 이런 것이 아닐까라는 생각들이 머리에 그려지고 있을 것입니다.

, 그럼 이벤트라는 것은 어떤 것인지 알아 봅시다. 지금 제가 사용하는 윈도우 2000 운영체제를 예를 들어 설명해 보겠습니다. 제가 컴퓨터를 사용하고 있다고 가정합니다. 컴퓨터를 사용하고 있는 지금 마우스를 움직이고, 키보드를 누르고, 창을 열고 있습니다. 지금 저는 수많은 이벤트들을 발생 시킨 것이죠. 이제 이해가 되었나요? 어떠한 사건이 없이는 프로그램은 동작하지 않습니다. 그 어떠한 사건이 바로 이벤트인 것이고, 우리는 이 사건을 받아서 어떠한 처리를 해줄 것인지 프로그래밍을 하면 되는 것입니다. , 생각보다 거대한 개념은 아닙니다. 그럼 본격적으로 이벤트를 학습해 보도록 하겠습니다.

 이벤트는 델리게이트를 통하여 구현 됩니다. 하나의 이벤트는 여러 개의 작업들이 추가 될 수 있어야 합니다. 그리고 그 작업들은 외부 메서드를 필요로 할 수도 있을 것입니다. 이런 작업을 위해서 델리게이트를 필요로 하게 되는 것입니다.
 

2. 이벤트(Event)


*이벤트 선언하기

event 선언된델리게이트 이벤트명;

 

그럼 이제 선언된 델리게이트를 이벤트와 연결하여 사용하는 이벤트 예제를 살펴 보도록 하겠습니다.

001: using System;

002: //델리게이트 선언

003: delegate void eventDelegate();

004: class EventTest

005: {

006:    // Event1 이라는 우리만의 새로운 이벤트를 선언해 주고,

007:    // 이 이벤트의 처리는 eventDelegate 타입의 delegate들이

008:    // 하게 된다는 것을 알립니다.

009:    public event eventDelegate ckEvent;

010:    // 어떤 버튼을 누를 때, 이 메서드가 호출된다고 가정 합시다.

011:    public void btnClick()

012:    {

013:           ckEvent();

014:    }

015: }

016: class MainClass

017: {

018:    static void Click()

019:    {

020:           Console.WriteLine("클릭 되었습니다.");

021:    }

022:    static void Main(string[] args)

023:    {

024:           //클래스 선언및 인스턴스화

025:           EventTest eTest = new EventTest();

026:          

027:           // 미리 정의한 이벤트 즉,ckEvent가 발생한 경우

028:           // eTest 라는 인스턴스에서 이 이벤트를 처리할 메서드

029:           // (핸들러, Delegate)를 지정합니다.

030:           eTest.ckEvent += new eventDelegate(MainClass.Click);

031:

032:           // 어떤 버튼이 눌려서 클릭 이벤트가 발생되었다고 가정합니다.

033:           eTest.btnClick();

034:    }
035: }


결과

클릭 되었습니다.

 

이제, 코드를 살펴 보면서 이벤트의 동작을 이해 해 봅시다. 9번 번째 줄에서 ckEvent 라는이벤트를 선언 하였고, ckEvent 이벤트는 앞서 3번째 줄에서 선언된 eventDelegate 형식을 가지게 됩니다.
그 아래 11번째 줄에 선언된 btnClick() 라는 메서드는 ckEvent()를 실행하고 있습니다. 여기서 우리는 이벤트를 메서드와 같은 형식으로 호출 할 수 있다는 것을 알 수 있습니다.
이제 MainClass안의 Main 메서드를 살펴 보도록 합시다. 먼저 클래스를 인스턴스화 하였습니다. 30번째 줄에서는 이벤트 동작에 의해 실행 될 메서드를 추가 하고 있습니다. 메서드를 추가하는 방법은 앞서 학습한 델리게이트의 형식을 똑같이 따르고 있습니다.

아직 이벤트에 대한 개념이 잘 잡히지 않는다 하더라도 너무 걱정 할 필요는 없습니다. 후에 윈도우 응용 프로그램을 다루게 될 것입니다. 그때 좀 더 자세히 이벤트에 대해서 언급 하도록 하겠습니다.

 

 

3.정리

이번 아티글에서는 델리게이트(delegate) 와 이벤트(Event)에 대해서 알아 보았습니다. 델리게이트는 이벤트뿐만 아니라 뒤에 학습하게 될 스레드에서도 활용되는 개념입니다. 무엇보다도 델리게이트에 대한 이해는 완벽히 다지고 이번 장을 넘어 가기 바랍니다.

 

 [펌] 훈스닷넷

Comments