소스코드리뷰(XXXVII) 컴포넌트 만들기 리뷰와 예제

[목차(도우미)]
함수군을 설계하여 사용함에 익숙해 지면 컴포넌트로 재구성하는 것은 아무것도 아닌데 어렵게 여겨지곤 한다. 부하 직원 중에 야무지기로 유명했던 들소(별명) 여직원도 자신은 객체 지향 설계를 못하겠다고 종종 말하곤 했는데, 그가 말한 객체 지향은 무엇을 두고 말했든지 간에 재사용을 가능하게 하는 객체 --- 컴포넌트 중심의 설계는 사고방식의 전환을 필요로 하는 것이다.

젊은 직원은 함수 베이스의 제조 공정에 익숙하고 함수군을 묶어서 컴포넌트로 구성하는데는 감각이 모자랄 수 있다. 그래서 이번에는 리뷰를 바탕으로 예제를 들어 읽는 사람에게 통찰력을 배양시키고자 한다.

예를 들어 CSV 파일(*.csv)이 있다고 하고 *.INI 파일과 유사하게
[SECTION]
1,aaa,bbb,...
2,bbab,rure,...
keys,value1,value2,...
등의 형태로 구성되었다고 하자. 그러면 [SECTION]-KEYS의 행을 얻는 기능을 설계해 보자

함수를 만들기라면
resultValue = GetCsvFileKeyValue(fileName, sectionName, keyName, default);
의 형태를 설계할 것이다. 이것은 윈도 API 집에서 자주 보는 함수 형태이다. 이것으로서 훌륭한 함수(function)이 된다.

이것을 클래스로 구현한다면? (델파이식 소스; 편의상 선언을 간략히 했다)
#1안
  1. TCsvFile = class(TObject)
  2.     public:
  3.         function GetKeyValue(fileName, sectionName, keyName, default : String):string;
  4. end;
  5. cf = TCsvFile.Create();
  6. resultValue = cf.GetKeyValue(fileName, sectionName, keyName, default);

이렇게 구현하게 되면 함수와 다를 바가 없다고 보이지만 사실은 설계적 결함이 있다. 함수 구현에서는 문제가 되지 않았는데 어디에 설계적 결함이 있을까?

인스턴스를 생성하고서 파일명을 변경할 수 있다는 점에 결함이 있다. 단지 키값을 읽어들이는 처리만 아니라 여러가지 고속 처리를 구현한다고 했을 때 파일 명이 바뀔 수 있다는 점은 언제나 위험적 요소가 된다.

어차피 개발자가 주의해서 메소드를 불러들이면 되지 않는가?
이 부분이 컴포넌트 개발과 함수 개발에 있어서의 설계 감각, 방식의 차이가 나타나는 부분이라고 해야 할 것이다. 제약사항이 존재하는 메소드를 정의하는 것은 좋은 습관이 아니다. 메소드의 호출에 순서가 존재해서는 좋은 컴포넌트가 되지 못한다. TCsvFile 컴포넌트를 효율적으로 사용함에 있어서 파일명 파라미터를 사용중 바꾸어서는 안된다는 것은 제약사항에 해당하는 것이다. 이런 제약 사항을 미연에 방지할 수 있도록 해야 하는 것이다.

해결책은 바로 constructor에 파일명을 넘겨주는 것이다.
#2안
  1. TCsvFile = class(TObject)
  2.     public:
  3.         function GetKeyValue(sectionName, keyName, default : String):string;
  4.         constructor Create(filename : string);
  5. end;

  6. cf = TCsvFile.Create(filename);
  7. resultValue = cf.GetKeyValue(sectionName, keyName, default);

Review Points
  • 필수 파라미터를 생성자에게 넘겨주라
  • 메소드를 자유롭게 하라
  • 메소드 호출의 순서를 두지마라
by 금메달.아빠 on 2011. 7. 25. 23:44