클래스 이야기

1

OOP vs NOOP

 

이 글은 http://www.owlnet.rice.edu/~comp212/99-fall/handouts/week1/person/ 을 인용하여 델파이 버전으로 제 방식대로 옮겨 본 것입니다.

여유시간이 되는대로 객체 및 델파이 또는 프로그래밍에 관한 주제를 지속적으로 강좌로 만들어갈 예정입니다.  http://cafe.naver.com/codeway 가시면 부족하지만 그 동안의 작업들을 보실 수 있습니다.

 

2004년 2월 20일, 류종택 드림.

 

 

 

Class 기법을 사용한다고 해서 모두 OOP(Object-Oriented Programming)라고 할 수는 없습니다.  객체지향적 사고를 갖지 않고서는 진정한 Class의 위력을 발휘하기 힘들기 때문입니다.  이는 마치 삽으로 밥을 떠먹는 꼴이라 할 수 있습니다.

그 객체지향적 사고에 대한 간단한 예를 지금부터 설명하고자 합니다.


 

 

 

NOOP(Non Object-Oriented Programming)의 예제 소스

 

 

[그림 1.1] Person의 Class Diagram

 

 

1: unit Person;

   2:

   3: interface

   4:

   5: Uses

   6:   Classes;

   7:

   8: Type

   9:   TGender = (gFemale, gMale);

  10:

  11:   TPerson = Class(TObject)

  12:   Private

  13:     { Private declarations }

  14:     FGender : TGender;

  15:   Public

  16:     { Public declarations }

  17:     Constructor Create(Gender:TGender);

  18:     Function  GetGender:String;

  19:   End;

  20:

  21: implementation

  22:

  23: Constructor TPerson.Create(Gender:TGender);

  24: Begin

  25:   Inherited Create;

  26:

  27:   FGender:= Gender;

  28: End;

  29:

  30: Function  TPerson.GetGender:String;

  31: Begin

  32:   Case FGender of

  33:        gFemale : Result:= '여성입니다.';

  34:        gMale : Result:= '남성입니다.';

  35:   End;

  36: End;

  37:

  38: end.

 

 

 

 

NOOP 예제 무엇이 문제일 까?

 

 

1: procedure TForm1.Button1Click(Sender: TObject);

   2: Var

   3:   JiHae, Ryu : TPerson;

   4: begin

   5:   JiHae:= TPerson.Create(gFemale);

   6:   Ryu:=   TPerson.Create(gMale);

   7:

   8:   ShowMessage('지혜는 ' + JiHae.GetGender);

   9:   ShowMessage('류는 '   + Ryu.GetGender);

  10:

  11:   JiHae.Free;

  12:   Ryu.Free;

  13: end;

 

 

위의 예제에서 각각 남성과 여성을 뜻하는 오브젝트 Ryu, JiHae는 같은 사람을 뜻하는 TPersion 클래스를 이용하여 생성됩니다.  그리고 생성될 때 성별을 입력하여 주었으며, 이후 자신이 남성인지 여성인지 알 수 있도록 내부에 FGender라는 Flag를 지니게 됩니다.

 

하지만, 코드가 해당 오브젝트가 남성인지 여성인지 알고자 오브젝트에게 물어볼 때 마다 오브젝트는 자신이 남성인지 여성인지 바로 알지 못하고 내부의 Flag를 이용하여 대답할 수 밖에 없습니다.

 

, 위의 두 객체는 사실상 어떠한 객체인지 불명확하다는 이야기가 됩니다.

 

 

 

OOP(Object-Oriented Programming)의 예제 소스

 

 

[그림 1.2] APerson의 Class Diagram

 

 

1: unit Human;

   2:

   3: interface

   4:

   5: Uses

   6:   Classes;

   7:

   8: Type

   9:   THuman = Class(TObject)

  10:   Private

  11:     { Private declarations }

  12:   Public

  13:     { Public declarations }

  14:     Function  GetGender:String; virtual; abstract;

  15:   End;

  16:

  17:   TWoman = Class(THuman)

  18:   Private

  19:     { Private declarations }

  20:   Public

  21:     { Public declarations }

  22:     Function  GetGender:String; override;

  23:   End;

  24:

  25:   TMan = Class(THuman)

  26:   Private

  27:     { Private declarations }

  28:   Public

  29:     { Public declarations }

  30:     Function  GetGender:String; override;

  31:   End;

  32:

  33: implementation

  34:

  35: Function  TWoman.GetGender:String;

  36: Begin

  37:   Result:= '여성입니다.';

  38: End;

  39:

  40: Function  TMan.GetGender:String;

  41: Begin

  42:   Result:= '남성입니다.';

  43: End;

  44:

  45: end.

 

 

 

OOP 예제 소스 무엇이 다른가?

 

 

1: procedure TForm1.Button2Click(Sender: TObject);

   2: Var

   3:   JiHae, Ryu : THuman;

   4: begin

   5:   JiHae:= TWoman.Create;

   6:   Ryu:=   TMan.Create;

   7:

   8:   ShowMessage('지혜는 ' + JiHae.GetGender);

   9:   ShowMessage('류는 '   + Ryu.GetGender);

  10:

  11:   JiHae.Free;

  12:   Ryu.Free;

  13: end;

 

 

위의 예제에서는 Ryu와 JiHae라는 오브젝트를 생성할 때, 이전과 달리 남성을 뜻하는 TMan과 여성을 뜻하는 TWoman으로 생성하여 주었습니다.  때문에 사람을 생성하고 “너는 남자다”라는 증표(Flag)를 넣어둘 필요가 없습니다.

 

각각의 오브젝트는 자신의 남성인지 여성인지 알려주기 위해 스스로 Flag에게 자신이 어떠한 성별인지 물어보지 않고 바로 대답할 수가 있었던 것입니다. 

 

, 자신의 성별을 알려줄 수 있는 명백한 방법을 알고 있는 것입니다.  이것은 TWomanTMan 객체가 서로 명백하게 구별되고 있다는 것을 뜻하기도 합니다.  “남자”라고 창조된 객체가 자신이 “남자”인지 혼동하는 일은 사라진 셈입니다.

 

 

 

객체지향적 사고

 

위의 두 가지의 예제에서 가장 두드러지는 차이점은 객체지향적 사고입니다.  두 번째의 예제에서는 객체지향에서 중요한 키워드인 “추상화”와 “다형성”의 개념이 사용되었습니다.

 

“추상화”의 개념은 THumanGetGender 메소드에서 사용되었습니다.  추상화란 표현하고자 하는 대상(객체)에서 의미 있는 특징만 간추리는 작업입니다.  “구체화”와 반대되는 개념으로서 생각하시면 됩니다.

현재 저희가 살펴보고 있는 예제에서는 성별을 알려주는 것에 포커스를 두고 있기 때문에, 사람이라는 객체 중에 의미 있는 것은 성별을 알려주는 동작입니다.

 

이후 THuman에서 상속 받은 각각 TWomanTMan의 경우에는 자신의 성별을 알려줄 수 있는 GetGender 메소드가 이름(호출되는 방식)은 동일하지만, 전혀 다른 동작(결과)을 하게 됩니다.  이것을 우리는 클래스의 “다형성이라고 부릅니다.

 

객체를 설계할 때, 우리는 구현해야 할 대상(객체)을 선별해 내고, 그 객체들 끼리 연관성이 있는 것들을 분별해 냅니다.  이어서 중복되는 요인들을 하나로 합쳐 부모 클래스를 생성하고, 각각의 객체들이 가지고 있는 다른 성향들은 이미 생성된 부모 클래스에서 상속 받은 후, 각자의 특징대로 클래스를 다시 정의하게 됩니다.

이것은 클래스의 상속의 기능과 추상화의 개념으로 가능한 일입니다.

 

또한 비슷한 동작이지만 클래스의 종류에 따라 서로 다른 동작을 하는 경우, 우리는 다형성이라는 개념을 사용하게 되는 것입니다.

 

정리하자면, 첫 번째의 예제에서는 클래스의 기술적인 면만 활용하여 대상을 표현하였을 뿐입니다.  이는 전혀 객체지향적인 사고라고 할 수가 없는 것입니다.

 

또한, 객체지향적인 예제에서 우리가 얻을 수 있는 것들은 다음과 같습니다.

l       단계적인 포커스

첫 번째 예제에서와는 달리 두 번째 예제는 사람이라는 관점에서 설계를 검토하고, 이어 남성과 여성이라는 관점에서는 사람이라는 클래스를 상속하여 이전의 과정을 생각하지 않아도 됩니다.  이로써 우리는 설계하려는 대상을 단계적인 포커스를 가지고 모든 단계를 상속하여 쉽게 정리할 수 있습니다.

l       확장성

만약 중성이라는 성별을 하나 더 늘여야 하는 경우가 발생한다고 가정하겠습니다.  이때 첫 번째 예제에서는 성별(TGender)이라는 데이터 타입을 추가해주어야 합니다.  즉, 추가적인 코딩이 필요하게 됩니다.  하지만, 두 번째의 예제에서는 이전의 코드는 손을 대지 않아도 됩니다.  단지 사람이라는 클래스에서 상속하여 중성이라는 클래스를 만들어 내면 됩니다.

 

 

 

 

끝으로

 

  클래스 및 델파이 그리고 개발 전반에 대한 이야기를 능력이 닺는 데까지 지속적으로 강좌를 작성하여 제 카페에 올리도록 하겠습니다.  강좌 내용을 자주 업데이트하기는 어려울 것 같습니다만, 최선을 다할 것이니 많은 관심 부탁 드립니다.

Posted by Real_G