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

델파이 강좌/문서
Delphi Programming Tutorial&Documents
[40] 11월 세미나 소스 리팩토링 예제
주정섭 [jjsverylong] 5066 읽음    2004-10-18 11:55
11월 세미나 소스 리팩토링 예제

[일러두기]
이글은 11월에 개최할 세미나 예제 중 하나이며, 다소 광고성 성격이 강함을 미리 일러두겠습니다. 11월경의 세미나때문에  최근 저의 강좌들이 다소 세미나 홍보성글인데 대해서 고개 숙여 양해를 구합니다. 남의 코딩 방식을 자주 보면 도움이 되는 경우가 많은데, 이 강좌를 저의 코딩 방식을 엿보는 기회로 삼으시기 바랍니다.
[일러두기 끝]

이글에 첨부한 프라젝트는, 아주 간단한 MDI 방식의 실행 파일로서 다음과 같은 기능을 가지고 있다(참고로 리팩토링이 안된 상태의 프라젝트 소스이다)

1. 프로그램을 종료할 때 Fading효과(조금씩 사라지는 효과)를 보여준다.
2. MDI 메인폼에 배경 그림을 표시한다.
3. 메인메뉴에 세개의 작업폼(MDI Child 폼)을 보이도록 하는 메뉴가 있다.
4. 동일 클래스의 작업폼을 2개 이상 만들지 못하도록 처리되어 있다.

한번 실행해 보면 모든 기능을 알 수 있는 아주 간단한 프로그램이다.

다음은 이 프라젝트의 메인폼 소스 파일 내용이다.

// FmMain.pas.. 리팩토링 이전의 상태

unit fmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus;

type
  TMainFrm = class(TForm)
  {..중략..}
  private
    procedure OpenForm(AFormClass:TFormClass);   
  public
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.dfm}

uses fmSub1, fmSub2, fmSub3;

var
  // For Form Painting
  BitMap : TBitMap;

procedure TMainFrm.FormCreate(Sender: TObject);
begin
  // Begin Form Fading Effect Code
  AlphaBlend := True;
  AlphaBlendValue := 255;
  // End Fading Effect Code

  // Begin Form Painting
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('깃털.BMP');
  // End Form Painting
end;

procedure TMainFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // Begin Form Fading Effect Code
  while AlphaBlendValue > 1 do
  begin
    AlphaBlendValue := AlphaBlendValue - 1;
    Sleep(10);// Change the sleep time to manage fading speed
  end;
  // End Fading Effect Code
end;

procedure TMainFrm.FormPaint(Sender: TObject);
var
  // Form Painting Vars
  X, Y, W, H: LongInt;
begin
  // Begin Form Painting
  with Bitmap do
  begin
    W := Width;
    H := Height;
  end;
  Y := 0;
  while Y < Height do
  begin
    X := 0;
    while X < Width do
    begin
      Canvas.Draw(X, Y, Bitmap);
      Inc(X, W);
    end;
    Inc(Y, H);
  end;
  // End Form Painting
end;

procedure TMainFrm.FormDestroy(Sender: TObject);
begin
  Bitmap.Free;
end;

// 동일 클래스의 폼을 2개 만들지 못하도록 처리
procedure TMainFrm.OpenForm(AFormClass:TFormClass);
var
  i: Integer;
begin
  for i := 0 to MdiChildCount - 1 do begin
    if MdiChildren[i].ClassType = AFormClass then
    begin
      MdiChildren[i].BringToFront;
      Exit;
    end;
  end;

  AFormClass.Create(Self);
end;

procedure TMainFrm.Sub11Click(Sender: TObject);
begin
  OpenForm(TSub1Frm); // 작업폼1 열기
end;

procedure TMainFrm.Sub21Click(Sender: TObject);
begin
  OpenForm(TSub2Frm); // 작업폼2 열기
end;

procedure TMainFrm.Sub31Click(Sender: TObject);
begin
  OpenForm(TSub3Frm); // 작업폼3 열기
end;

end.

아마도, 대부분의 델파이 개발자들은 이런식으로 메인폼 소스 파일을 작성할 것이다. 다시 말해서 전형적인 델파이 방식 메인 폼 소스 파일일 것이다.

이 소스를 주위 델파이 개발자들에게 보여주고, 잘못된 점을 찾아보라고 했다. 대부분 별다른 문제점을 찾아 내지 못했다.
사실 너무 간단하기도 하지만, 얼핏 봐서는 잘못된 점이 보이지 않을 수도 있다. 코드 중복도 거의 없으며, 상당히 깔끔하게 작성된 메인 폼 소스처럼 보일 것이다.

그러나, 이 전형적인 메인 폼 소스 파일에는, 후일 유지보수와 디버깅에 치명적인 장애물이 될 수 있는 함정들이 여러 군데에 걸쳐 있다. 이 치명적 장애물이 무엇인지, 어떻게 실제로 리팩토링을 해야 하는지는 이번 세미나에서 굉장히 중요한 주제 중의 하나이므로, 지금 이글에서 여러분들에게 알려주지 못함을 양해해 주시라.

이 강좌에서는 이 메인폼 소스 파일을 리팩토링한, 결과 소스만 보이고자 한다.

// fmMain.pas ...리팩토링한 후의 메인 폼 소스

unit fmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, EtcUtil;

type
  TMainFrm = class(TForm)
      {.. 중략...}
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.dfm}

uses fmSub1, fmSub2, fmSub3;

procedure TMainFrm.FormCreate(Sender: TObject);
begin
  // Fading 효과 설정
  TFadingEffect.Create(Self).Init();
  // 배경 그림 설정
  TBackGround.Create(Self).Init('깃털.bmp');

  // 작업 메뉴 초기화
  mnuJobForm.Add( TMenuItem.Create(Self).Init('Sub1 폼 보이기', TSub1Frm) );
  mnuJobForm.Add( TMenuItem.Create(Self).Init('Sub2 폼 보이기', TSub2Frm) );
  mnuJobForm.Add( TMenuItem.Create(Self).Init('Sub3 폼 보이기', TSub3Frm) );
end;

end.

리팩토링한 소스 파일은 매우 간략해져서, 프로그램 흐름이 한 눈에 들어오는 구조로 변했다. 특히 리팩토링이 안된 버전에 비해서 이벤트 메서드 수가 현저히 작다. 보시다 시피 Form의 OnCreate 이벤트 고작 하나 뿐이다.

리팩토링한 결과 소스를 본 사람 중에는, 왜 Free 호출이 없는가 궁금해 하는 사람도 있을 것 이다. 이런식으로 코딩하면 객체가 파괴되지 않아서 메모리 누수 현상이 발생하지 않는가 의아해할 수도 있다. 그러나, 이것이 바로 자동 파괴 개념이다. 파괴를 안하는 것이 아니라 파괴자 호출을 자동화하는 것이다.

객체지향과 델파이에 매우 능한 개발자라면, 내가 어떻게 리팩토링했는지, 이 소스를 보고 상당 부분 이미 짐작했을 수도 있다.

사실 리팩토링은 끝이 없다. 매우 간략해 보이는 두번째 메인 폼 소스조차도, 리팩토링을 또 할 수 있는 여지는 많기 때문이다. 지나친 리팩토링은 개발기간을 가중시키므로, 바람직하지 않지만, 적절한 리팩토링은 개발 효율을 높일 수 있다는 사실을 이 강좌의 결론으로 두고자 한다.

업무 변경 사항이 잦아서 소스가 꼬이기 시작한다면 리팩토링을 고려할 시기가 된 것이다.

http://cafe.daum.net/delphinegong

+ -

관련 글 리스트
40 11월 세미나 소스 리팩토링 예제 주정섭 5066 2004/10/18
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.