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

델파이 강좌/문서
Delphi Programming Tutorial&Documents
[39] 소스 파일의 체계적 분리를 위한 간단한 몇가지 방법
주정섭 [jjsverylong] 6441 읽음    2004-10-15 15:42
소스 파일의 체계적 분리를 위한 간단한 몇가지 방법

1. 메인폼에 전역 변수나 전역 함수를 두지 말라.

메인 폼은 오로지 작업폼 처리와 메뉴 처리에 대한 코드만 놓여 져야 한다. 여러 유닛이 공통 사용하는 전역 변수나 전역 함수가 함께 있으면, 후일 소스 가독성에 별로 좋지 않다. 전역 함수와 전역 변수를 보관하는 별도 유닛을 만들고, 필요하다면 메인폼에서 그 소스 파일을 uses 문에 나열하고 전역변수나 전역함수를 참조함이 바람직하다. 이는 다른 작업폼들도 마찬가지다.

이렇게 함으로 해서, 전역 명칭 때문에 메인폼과 작업폼이 서로를 uses문에 나열해야할 필요성이 사라지게 된다. uses 문은 필요 불가결하긴 하나, uses문을 간결하게 유지하는 것이 좋으며, 유닛 상호간의 순환 참조는 가급적 피함이 좋다. 참고로, 유닛 상호 참조란 A와 B란 유닛이 서로를 uses문에 나열하고 서로의 명칭을 참조해야 하는 경우를 말한다.

(전역변수를 별도 유닛으로 분리한 예)
// GlobalVar.pas
unit GlbalVar;
{...중략...}
var
    Userid : String;    // 로그인한 사용자 아이디를 보관하는 전역 변수
    UserLevel : integer; // 로그인한 사용자 등급을 보관하는 전역 변수
    UserPart :     string;  // 로그인한 사용자의 부서정보를 보관하는 전역변수
   
사실 이보다 더 좋은 방법은 연관성있는 전역변수들끼리 모아서 Singleton 클래스를 만드는 것이다. 델파이는 내부적으로 이런 용도의 Singleton 클래스들이 이미 있다. Screen, Application, Clipboard, Printer 등이 바로 그것이다.   

2. 문자열 상수를 별도 유닛으로 덜어내라.

http://cafe.daum.net/delphinegong

간단한 프라젝트에서는 이 방법이 별로 효용이 없을지 모르지만, 대형 프라젝트에서는 그렇지 않다. 동일 문자열의 반복 또한 피해야할 부분이며, 동일 문자열 반복은 후일 유지 보수에 악영향을 미친다. 가장 대표적인 경우가 필드명을 문자열로 참조할 때이다. 델파이 프로그램을 보면 다음과 같은 코드를 자주 본다.

(예)

table1.fieldbyName('userid').asString := 'abcd';
...
if not table1.locate(['userid'], ['abcd']) then
    ShowMessage('해당 고객은 존재하지 않습니다.');

이 방식 보다 좀더 나은 방식은 다음과 같이 하는 것이다.

const
    fld_userid = 'userid';
    err_user_not_found = '해당 고객은 존재하지 않습니다.';
   
{...중략...}

table1.fieldbyName(fld_userid).asString := 'abcd';

if not table1.locate([fld_userid], ['abcd']) then
    ShowMessage( err_user_not_found);
   
   
이런 방식으로 문자열 상수를 분리하면, 후일 userid 필드명이 변경되었을 때 프로그램 전체 소스를 찾아볼 필요 없이, 필드명을 정의한 상수 부분만 수정하면 된다. 이 방법을 좀더 응용하여 resourcestring 예약어를 사용하여 문자열을 리소스로 덜어내는 방법도 있다. 이 방식은 한국어가 아닌, 다른 언어로 프로그램을 변경할 때 매우 용이해 진다.

resourcestring 예약어 사용방법은 여러 델파이 관련 사이트 게시판에서 찾아 볼 수 있다.

3. Visual 콤포넌트와 Non Visual 콤퍼넌트를 분리하라.

프로그램 실행시 폼 위에서 어떤 식으로든 표시되는 콤포넌트들은 Visual이라고 하며, 그렇지 않는 것을 Non visual 콤퍼넌트라고 한다.

델파이 매뉴얼에 보면, 여러 폼들이 공통으로 사용하는 Non visual 콤포넌트를 DataModule에 두고 이를 각 폼에서 uses하여 사용하라고 권장하고 있다. 그런데 많은 델 개발자들이 착각하고 있는 사실이, 데이타모듈에는 TDataSet계열 콤포넌트만 두는 것으로 생각하고 있다는 것이다. 그러나 데이타모듈에는 거의 모든 Non Visual 콤포넌트를 둘 수 있다.

ActionList, ImageList등도 데이타모듈에 두면 편한 콤포넌트들이다. 경우에 따라서는 MainMenu, PopupMenu도 데이타모듈에 두면 좋은 경우가 있다.

델파이 매뉴얼에서는 언급하지 않았지만, 각 폼마다 자신 전용의 데이타모듈을 만들어 사용하는 방법이 있다. 그래서 Non Visual 콤포넌트들은 데이타모듈에 두고, Visual 콤포넌트들은 폼에 두는 것이다. 이렇게 하면 어느 쪽이든 한번에 봐야할 소스의 량, 즉 어떤 부분을 수정하기 위해서 봐야할 코드 량이 줄어들게 되므로, 좀더 직관적인 소스 구성이 된다.

하나의 폼마다 하나의 데이타모듈을 거느리는 이 방식이 델파이 방식의 도큐멘트 뷰 방식으로, 이번 세미나 때 언급할 내용이기도 하다. 이 방식은 규모가 작은 프라젝트에서는 별로 도움이 안될수도 있지만, 수십개의 폼을 만들어 사용해야 하는 복잡한 프라젝트의 경우, 소스 분리에서 아주 지대한 공헌을 한다.

4. 유틸러티 코드와 어플 코드를 분리하라.

사실 이방법이 가장 이상적이긴 하나, 매우 심오한 클래스 개념과, 다소 심도있는 델파이 지식이 있어야 가능한 방법이다.이 방법은 초보들이 쉽게 할 수 있는 방법은 아니지만, 가장 소스 분리 효과가 뛰어난 방법이며, 특히 대형 프라젝트에서 매우 큰 효과를 낸다.

이 개념을 달리 말하면, 어떤 기능 구현을 위해서 코딩해야 할, 이벤트 메서드들을 분리하여 별도로 클래스화하란 것이다. 어떤 개발자는 이 개념을 smart class라고 부르기도 한다. 이 방법은 델파이 폼 내의 이벤트 메서드 혼란과 난무를 가장 효과적으로 막는 방법이기도 하다. 따라서, 어려운 만큼 그 활용도가 무궁무진하므로 이번 세미나의 주제 상당수가 여기에 할애될 것이다.

5. 할수만 있다면 무조건 코딩 과정을 자동화하라.

프로그램을 만드는 목적은 다른 사람들의 반복적 수작업을 자동화하는 것이다. 그렇다면 개발 과정이나 코딩 과정이 반복적이라면 이를 자동화하는 것이 당연하다. 몇몇 개발자와 이야기를 하다보면 의외의 반론을 듣게 된다. 객체를 명시적으로 생성하고 명시적으로 파괴하는 것이 더 좋다는 것이다.

나는 이 의견에 완전히 반대다. 할수만 있다면, 생성과 파괴 모두를 자동화하는 것이 더 좋다. 일반적으로 생성자(Create) 호출은 자동화가 불가능한 경우가 많지만, 상당수의 경우 파괴자(Free) 호출은 자동화할 수 있다.

델파이는 Owner란 개념으로 콤포넌트 파괴를 자동으로 처리한다. 이 때문에 델파이 개발자들은 폼에 놓여진 콤퍼넌트에 대해서 Free를 일일이 호출할 필요가 없다. 델파이 VCL 상당수 클래스들은 리소스 할당과 파괴를 자동으로 하도록 처리되어 있다. 예를 들어, TTable의 경우, Free를 호출하면 자동으로 Close를 호출하도록 설계되어 있다.

델파이의 interface를 사용해본 사람은, interface의 자동 파괴 개념을 알 것이다. 볼랜드 개발자들이 심혈(?)을 기울여서 interface에 자동 파괴 개념을 접목한 이유는, 자동 파괴가 월등히 편하다는 것을 잘 알기 때문이다. 비주얼 씨로 interface를 사용해본 사람은 AddRef와 Release 호출이 얼마나 짜증나는지 경험해본 적이 있을 것이다.

파괴자 호출 자동화가 불가능한 경우도 있다. 그렇다면, 이런 부분은 라이브러리 코드로 한정해야 한다. 수정이 잦은 어플 코드에서 파괴자 호출을 항상 신경쓰야 한다는 것은, 매우 짜증나는 일이다. 결론인즉, 어플 코드에서 만큼은 파괴자 호출을 자동화하란 것이다.

외울게 많고 절차가 많은 방식으로 코딩을 하지 말라는 것이다. 이에 대한 주제 또한 이번 세미나의 일부이며, 조만간 여기에 대한 예제를 올릴 작정이다.

http://cafe.daum.net/delphinegong

+ -

관련 글 리스트
39 소스 파일의 체계적 분리를 위한 간단한 몇가지 방법 주정섭 6441 2004/10/15
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.