Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 강좌/문서
Delphi Programming Tutorial&Documents
[46] 상속(inheritance)과 연결(association)에 대해서
주정섭 [jjsverylong] 7549 읽음    2004-11-04 11:59
상속(inheritance)과 연결(association)에 대해서

객체지향에서 상속은 매우 막강한 개념이지만, 상속으로 모든 문제를 풀려하면 더 꼬이는 경우가 많이 발생한다.

상속의 가장 큰 단점은 클래스 관계를 복잡하게 만든다는 것이다. 여러 단계의 상속은, 이해하기도 힘들 뿐더러 수정도 쉽지 않다. 상속은 All or Nothing 개념이다. 이말인즉, 상속은 상위 클래스의 모든 기능을 하위 클래스로 전이 한다는 것이다. 이 때문에, 상위 클래스의 기능 중에서 어떤 기능을 제거하거나 추가하려면, 그 상위 클래스로 부터 상속받은 새로운 클래스를 만들고 그 기능을 override해야 한다는 문제점이 있다.

이 과정이 반복되면 쪼잔한 기능 때문에 수많은 클래스 계층 구조가 생기므로, 객체지향 고수들은 다른 방법을 찾아보라고 권한다.

상속의 큰 문제점 중의 하나가, 기능 추가는 비교적 쉬운 반면에, 상위 클래스의 특정 기능을 완전히 없애버리는 것은 매우 어렵다는 것이다.

상속의 또 다른 문제점은, 현대 상당수 객체지향 언어들이 다중 상속을 지원하지 않는다는 것이다. C++을 제외하고는 자바, 델파이, 시샵 모두 다중 상속을 지원하지 않는다. 대부분의 현대 언어들이 다중 상속을 지원하지 않는 이유는 다중 상속이 득보다 실이 많기 때문이다. 다중 상속은 프로그램 구조를 엄청나게 복잡하게 만든다.

그런데, 다중 상속을 지원되지 않는 델파이에서, 이 다중 상속 비슷한 기능이 필요한 경우가 많다. 예를 들어 Form에 다음과 같은 기능을 추가하고 싶다고 가정하자.

1. 폼에 배경 그림을 삽입하는 기능(BackGround Image)
2. 현재 입력 포커스를 가진 콘트롤을 다른 색으로 표시하는 기능(Focused Control)
3. 폼이 닫힐 때 Fade in 하는 기능(Fade in)

이 세가지 기능을 모두 구현한 TEnhancedForm이라는 클래스를 만들었다고 가정하자. 기존 프라젝트의 모든 작업폼 소스를 검색하여 다음 라인을 수정해야 할 것이다.

TSub1Frm = class(TForm)                 // 이런 라인을
=> TSub1Frm = class(TEnhancedForm) // 이렇게 수정해야 할 것이다.

새롭게 프라젝트를 만드는 경우가 아니라면, 기존 폼 클래스를 이런식으로 바꾼 다는 것은 때로는 엄청난 실수를 유발할 가능성이 있다.

그런데, 모든 작업폼이 이 세가지 기능 모두를 필요로 하면 아주 바람직할 것이다. 그러나, 실전 프로그램에서 대부분의 작업 폼은 위 세 기능중 어떤 기능도 필요 없는 폼도 있을 수 있으며, 1가지 기능만, 혹은 2가지 기능만, 혹은 세가지 모두 식으로, 요구하는 기능 갯수가 다르다는 것이다.

이에 대한 해결 방법으로, 각 기능을 On Off 하는 속성을 TEnhancedForm 클래스에 추가하고, 각 메서드들이 이 필드를 참조하여, 특정 기능을 사용하거나 않게 만들 수 있다.

TEnhancedForm = class
    {중략}
    property BackGroudOn : boolean ;    // 배경그림 기능 토글
    property FocusOn : boolean ;            // 포커스 콘트롤 기능 토글
    property FadeOn : boolean ;                //
end;

{중략}

// 실제 작업폼 소스에서
TSub1Frm = class(TEnhancedForm)
    ...
end;

...

procedure TSub1Frm.FormCreate(sender:TObject);
begin
    // 특정 기능을 On Off함
    BackGroundOn := True;
    FocusOn := False
    FadeOn := True;
end;

이런 TEnhancedForm 클래스를, 흔히 그랜다이저 울트라 슈퍼 마켓 클래스라고 한다. 단일 클래스가 너무 많은 기능을 포함하므로, 그 클래스는 무지 복잡한 구조를 가지게 되고, 이 때문에 각 메서드의  코드 또한 무지 복잡하게 꼬이게 된다. 이런 클래스는 조만간 골치아픈 디버깅에서 벗어나지 못할 가능성이 매우 크다. 가급적 한 클래스는 하나의 목적만 수행함이 바람직하다.

상속을 사용하는 다른 대안으로, 다음과 같이 각 기능을 세분화한, 여러 클래스를 만드는 방법이 있다.

TBackGroundForm, TFocusForm, TFadeForm, TBackGroundFocusForm, TBackGroundFade,  TFocusFadeForm 등등 엄청나게 많은 클래스를 만드는 것이다. 이 방식은 앞에 소개한 방법보다 더욱 않 좋은 방법이다. 특정 기능이 필요한 폼마다, 올바른 폼 클래스에서 상속받을 것을 명시하는 코딩 절차서를 작성한다면, 엄청나게 복잡한 절차서를 만들어야 할 것이다.

결론인즉, 이런 경우는 상속이 좋은 대안이 아니다. 다른 방법을 찾아봐야 한다. association을 대안으로 찾아 봐야 한다. 대부분의 경우 Association은 기존 클래스의 상속 구조를 건드리지 않으면서, 원하는 기능을 추가하는 용도로 사용한다. 패턴의 상당수가  association을 사용하는 대부분 이유도 이러하다.

만일 다음과 같이 association개념을 사용하여 각 기능을 구현하는 클래스를 만들었다고 가정하자.

TBackGround : 폼에 배경 그림을 삽입하는 기능을 구현한 클래스
TFocusControl : 포커스를 가진 콘트롤을 다른 색으로 표시하는 기능을 구현한 클래스
TFadeIn : 페이드 인하는 기능을 구현한 클래스

이제 각 작업폼들은, 자신의 OnCreate 이벤트에서 다음과 같이 원하는 기능만 추가할 수 있을 것이다.

procedure TSub1Frm.FormCreate(sender:TObject);
begin
    TBackGround.Create(Self);     // 배경그림이 필요하면 이 라인 삽입
    TFocusControl.Create(Self);    // 포커스 콘트롤에 대한 반전색 처리가 필요하면 이 라인 삽입
    TFadeIn.Create(Self);    // 페이드인 효과가 필요하면 이 라인 삽입
end;

TBackGround, TFocusControl, TFacdIn 클래스의 입장에서는, 작업폼이 TForm에서 상속 받았든, 어떤 상위 폼에서 상속받았던 전혀 개의치 않는다. 이 클래스들은 오로지 특정 기능을 전담 처리하는 역할만 한다. Form은 이 클래스들을 필요로 하지만, 필요없다면 언제든지 헌신짝처럼 버릴 수 있다.

작업폼들은 배경처리, 포커스 콘트롤 처리, 페이드인 처리 같은 유틸러티 코드를 포함할 필요가 없기 때문에, 봐야할 코드량이 줄게 된다. 즉 월등히 유지보수가 쉬워질 것이다. 후일 특정 기능이 필요없다면, 그 라인을 삭제하거나 코멘트화면 될 것이다. 즉, 기능의 추가 삭제가 훨씬 더 쉬워진다는 것이다.

혹자는 위와 같은 코딩 방식을 클래스 객체를 만들어 던져 둔다고 비난하는데, 사실 이 방법은 객체의 생성자와 파괴자 호출 시점을 이용하는, C++의 오래된 개발 팁중의 하나일 뿐이다. 객체를 생성하는 그 자체로 어떤 일이 자동으로 실행되도록 하는 개념이다.

내가 쓴 내공쌓기 상당수의 예제들이 이런 클래스 만들기 방법이라고 해도 과언이 아니다. 의외로 많은 델파이 개발자들이 이 방법을 잘 모르고 있다는 것이다. 알고보면 매우 간단하면서 편한 이방법은 이번 세미나의 중요한 주제이다. 아직 이 방법을 사용하지 않았다면 적극 사용해보길 권하고 싶다.

http://cafe.daum.net/delphinegong 델파이 강좌 주정섭

+ -

관련 글 리스트
46 상속(inheritance)과 연결(association)에 대해서 주정섭 7549 2004/11/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.