C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[12602] 델파이 코드 리팩토링 문제(다 함께 풀어 봅시다)
주정섭 [jjsverylong] 5034 읽음    2007-01-04 18:28
델파이 리팩토링 연습 문제

밑의 함수는 지인으로 부터 받은 소스에 포함되어 있던 함수중 하나이다.

이 함수의 역할은 컴에 설치된 문서(워드, 엑셀, 아래아한글 등등) 타입들을 알아내고, 이 정보들을 바탕으로 FileOpen 다이얼로그의 filter 속성으로 사용할 문자열을 얻어 내는 것이다. 아래는 그 소스인데, 소스 구조는 매우 간단하다.

function GetFileFilter:String;
var
    checkVal:OleVariant;
begin
    Result := 'Image All(*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd)|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd|';
   
    try
        checkVal := CreateComObject(CLASS_HwpCtrl);
        checkVal := Unassigned;
        Result := Result + 'HWP Document(*.hwp)|*.hwp|';
    except
        RemoveFileDocKind(dkHwp);
    end;

    try
        checkVal := CreateOleObject('WORD.Application');
        checkVal := Unassigned;
        Result := Result + 'MS-Word(*.doc)|*.doc|';
    except
        RemoveFileDocKind(dkMsWord);
    end;

    try
        checkVal := CreateOleObject('Excel.Application');
        checkVal := Unassigned;
        Result := Result + 'MS-Excel(*.xls)|*.xls|';
    except
        RemoveFileDocKind(dkMsExcel);
    end;

    try
        checkVal := CreateOleObject('PowerPoint.Application');
        checkVal := Unassigned;
        Result := Result + 'PowerPoint(*.ppt)|*.ppt|';
    except
        RemoveFileDocKind(dkMsPPt);
    end;

    try
        checkVal := CreateComObject(CLASS_IF_);
        checkVal := Unassigned;
        Result := Result + 'HunminWord Document(*.gul)|*.gul|';
    except
        RemoveFileDocKind(dkHun);
    end;

    Result := Result + 'Adobo PDF File(*.pdf)|*.pdf|PostScript(*.ps)|*.ps|Encapsulated PostScript(*.eps)|*.eps|';
end;


그런데 이 함수는 몇가지 문제점이 있다.

첫번째로 모양이 매우 비슷한 try...except 구문이 여러번 반복된다는 것이다. 반복되는 구조의 코드는 제거함이 옳을 것이다.

두번째로 후일 새로운 문서 타입을 추가해야할 때, 이 try except 구문이 또 반복 추가되고, 새 문서 타입 추가하기가 그리 쉽지 않다.

이 두문제를 해결할 수 있도록 이 코드를 정리해 보자. 리팩토링이란 기존 코드의 기능은 그대로 유지하면서도, 더욱 깔끔하고 정갈한 구조를 가지는 코드로 변경하는 작업이다. 이 코드를 깔끔하게 정리해 주시라. 가장 잘 정리한 사람에게는 큰절로 보답함과 더불어서, 공약일 가능성이 매우 농후하지만, 대구에 방문시 귀빈 대접을 받을 수 있는 영광을 드리도록 하겠다.

내가 정리한 코드는 조만간 올리도록 하겠다. 혹시 나보다 더 잘 코드를 정리한 사람이 있다면 부끄러워서 내것은 못올릴 수도 있겠다.
초보대왕 [sauron]   2007-01-04 18:52 X
--  이 코드를 깔끔하게 정리해 주시라.
-- 가장 잘 정리한 사람에게는 큰절로 보답함과 더불어서,
-- 공약일 가능성이 매우 농후하지만, 대구에 방문시
-- 귀빈 대접을 받을 수 있는 영광을 드리도록 하겠다

싫다 니가 하라.
김상면 [windyboy]   2007-01-04 19:38 X
켁....
'싫다 니가 하라.'
넘 하당....
어째 좀 넘하신당.

그럼
cc1232 [cc1232]   2007-01-04 22:03 X
음..개인적으로 답변이 기대가 되는 글이네요. 리팩토링이다 패턴이다 대략 공부하기는 했지만 머리 속에 구체적인 그림이 그려지지 않아서 어느 정도까지 해야 좋은건지 대략 난감인데, 많은 분들이 답변을 적어줘서 저같은 사람에게 가르침을 주시면 좋겠네요.
박지훈.임프 [cbuilder]   2007-01-05 03:23 X
음.. 코드를 짜볼 정신은 없고..
또 아래아 한글이나 훈민정음이 없기도 하고 해서 대략 생각만 해보면...

CreateComObject와 CreateOleObject 호출 두가지로 나뉘어진 걸 하나로 합치는 것이 중요할 거 같은데.. 둘다 ProgID 기반, 그러니까 CreateOleObject로 통일하는 편이 좋겠네요. CLASS_HwpCtrl이나 CLASS_IF_ 둘다 해당 ProgID 문자열이 있을테니까요.

그런 후에 각 ProgID와 필터 문자열, TDocKind의 레코드 혹은 클래스를 만들고 각 문서 타입에 해당하는 값들을 집어넣으면 될 듯...

그리고 RemoveFileDocKind()를 봐서는, 미리 TDocKind 들을 몽땅 다 등록된 것으로 간주한 다음 CreateOleObject 확인이 실패할 때마다 제거하는 방식으로 코딩한 거 같은데..  저라면 except에서 이미 등록된 TDocKind 값들을 '제거'하기보다는 except 바로 앞에서 TDocKind 값을 추가하는 쪽으로 코딩하겠습니다.
윤승환 [epilogs]   2007-01-05 10:33 X
function GetFileFilter():String;
  function  AddWordFiler(classid:TGUID;filter:string;docktype:TDockType;var filterlist:string) :string;  overload;
  var
    checkVal  :OleVariant;
  begin
    try
        checkVal := CreateComObject(classid);
        checkVal := Unassigned;
        Result  := filter;
    except
        RemoveFileDocKind(docktype);
        Result  :='';
    end;
  end;
  function  AddWordFiler(classname:string;filter:string;docktype:TDockType;var filterlist:string)  :string;  overload;
  begin
    result  :=AddWordFiler(ProgIDToClassID(classname),filter,docktype,filterlist);
  end;
begin
  result  :='Image All(*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd)|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd|';

  AddWordFiler(CLASS_HwpCtrl,'HWP Document(*.hwp)|*.hwp|',dkHwp,Result);
  AddWordFiler('WORD.Application','MS-Word(*.doc)|*.doc|',dkMsWord,Result);
  AddWordFiler('Excel.Application','MS-Excel(*.xls)|*.xls|',dkMsExcel,Result);
  AddWordFiler('PowerPoint.Application','PowerPoint(*.ppt)|*.ppt|',dkMsPPt,Result);
  AddWordFiler(CLASS_IF_,'HunminWord Document(*.gul)|*.gul|',dkHun,Result);

  result  :=result + 'Adobo PDF File(*.pdf)|*.pdf|PostScript(*.ps)|*.ps|Encapsulated PostScript(*.eps)|*.eps|';
end;
이경환.단디 [lncsoft]   2007-01-05 10:42 X
function GetFileFilter:String;
type
  TDocType = Record
    docId : String;
    filter : string;
    dockKind : integer;
    IsOle: Boolean;
  end;
const
  docTypes : array[0..2] of TDocType = (
    (docId:'WORD.Application'; filter:'MS-Word(*.doc)|*.doc|'; dockKind:dkWord; IsOle:true),
    (docId:'Excel.Application'; filter:'MS-Excel(*.xls)|*.xls|'; dockKind:dkExcel; IsOle:true),
    (docId:'{26319A34-0ADB-4F04-8EFD-4E6679644879}'; filter:'HWP Document(*.hwp)|*.hwp|'; dockKind:dkHwp; IsOle:false)
  );
  function checkFileServer(docId: string; docKind: integer; IsOle: Boolean): boolean;
  var
    checkVal: OleVariant;
  begin
    result:= false;
    try
      try
        if IsOle then   
          checkVal:= CreateComObject(docId)
        else
          checkVal:= CreateOleObject(StringToGuid(docId));
        result:= true;
      except
        RemoveFileDocKind(docKind);
      end;   
    finally
      checkVal:= Unassigned;
    end;   
  end;

begin

    Result := 'Image All(*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd)|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd|';

    for I := Low(docTypes) to High(docTypes) do
    begin
      if checkFileServer(docTypes[i].oleType, docTypes[i].docKind, docTypes[i].IsOle) then
        begin
          Result := Result + docTypes[i].filter;
        end;
    end;
   
    Result := Result + 'Adobo PDF File(*.pdf)|*.pdf|PostScript(*.ps)|*.ps|Encapsulated PostScript(*.eps)|*.eps|';
end;
이경환.단디 [lncsoft]   2007-01-05 10:45 X
헉...글 올리고 보니 한가해서 올린거 같네...
...바쁜척 하러 가야징~~~
미노 [wyb330]   2007-01-05 11:17 X
type
  TDocumentType = (dtHWP, dtWord, dtPowerpoint, dtExcel, dtHunminWord);
  TDocumentFilter = class
  private
    FDocumentType: TDocumentType;
  public
    class function DocumentFilter(Filter: TDocumentType): string;
    function GetDocumentFilter: string;
    property DocumentType:TDocumentType read FDocumentType write FDocumentType;
  end;

const
  DocumentType: array [1..5] of TDocumentType = (dtHWP, dtWord, dtPowerpoint, dtExcel, dtHunminWord);

implementation

{ TDocumentFilter }

class function TDocumentFilter.DocumentFilter(Filter: TDocumentType): string;
begin
  case Filter of
    dtHWP: Result:= 'HWP Document(*.hwp)|*.hwp|';
    dtWord: Result:= 'MS-Word(*.doc)|*.doc|';
    dtExcel: Result:= 'MS-Excel(*.xls)|*.xls|';
    dtPowerpoint: Result:= 'PowerPoint(*.ppt)|*.ppt|';
    dtHunminWord: Result:= 'HunminWord Document(*.gul)|*.gul|';
  else result:= '';
  end;
end;

function TDocumentFilter.GetDocumentFilter: string;
begin
  Result:= DocumentFilter(FDocumentType);
end;


function GetFileFilter:String;
var
  I: Integer;
begin
  Result:= 'Image All(*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd)|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.pcx;*.tif;*.tiff;*.psd;*.pdd|';
  for I := Low(DocumentType) to High(DocumentType) do
    Result:= Result + TDocumentFilter.DocumentFilter(DocumentType[I]);
  Result:= Result + 'Adobo PDF File(*.pdf)|*.pdf|PostScript(*.ps)|*.ps|Encapsulated PostScript(*.eps)|*.eps|';
end;

+ -

관련 글 리스트
12602 델파이 코드 리팩토링 문제(다 함께 풀어 봅시다) 주정섭 5034 2007/01/04
12622     Re:델파이 코드 리팩토링 문제(다 함께 풀어 봅시다) 주정섭 2567 2007/01/08
12611     Re:델파이 코드 리팩토링 문제(다 함께 풀어 봅시다) 사악신 2213 2007/01/05
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.