[Step by Step] 주석과 문서 자동화

변경 내역

  1. 2006.08.22 작성.

이 글은 월간 마이크로소프트웨어(일명 마소) 2006년 9월호 Step by Step 칼럼에 기고한 글입니다. 물론 구성이나 내용 상의 차이가 있을 수 있습니다.

지난 7월에 친분이 있는 개발자와 메신저로 이런저런 대화를 나눴다. T-SQL에 관한 질문과 답변을 한참 주고 받고 있었다. 그러다가 혹시 소스에 주석을 다는 것에 대해서 어떻게 생각하세요? 견해라 할까?라는 질문을 받게 됐다. 필자가 스택 구현조차 못해서 쩔쩔 매고 있을 무렵부터 주석에 관한 논쟁은 있었고, 이제는 지루한 감마저 든다. 하지만 필자는 조금은 새로운 측면에서 이 문제에 접근해보고자 한다.

최재훈 | 필자는 복학을 앞두고 전에 없이 평온한 생활을 즐기고 있다. 패턴이나 소프트웨어 공학 책을 읽고, 자전거 산책을 즐긴다. 아마도 대부분의 독자는 일상에 치여 바쁘게 살아가고 있을 테지만, 책 한 권을 가방에 넣고 지하철에서 짬짬이 읽는다면 마음의 여유를 찾을 수 있으리라 믿는다.

소스코드에 주석을 다는 일을 당연하게 받아들이기도 하지만, 사실 그것으로 끝나버리면 투자한 시간이 아깝다. 주석을 추가한 후에 별도의 클래스 명세서를 작성하는 경우도 있는데, 이 두 가지를 한번에 낚기 위해서 문서 자동화 도구를 활용할 수 있다. 프로그래밍 언어에 따라 Doxygen (C, C++, Java 등), NDoc (C#), Javadoc (Java) 등을 사용하는데, 사용법이 유사해서 추가적인 오버헤드는 거의 없다. 단순히 정해진 양식에 따라 주석을 달기만 하면 된다.

이렇게 주석을 단 후에 간단한 절차만 따르면 MSDN 라이브러리나 JAVA API 문서와 같은 훌륭한 명세서를 얻게 된다. 일부 자동화 도구는 클래스 다이어그램까지 자동 생성해 준다. 물론 도구에 손발이 묶여버리는 것은 아니다. 필요하다면 다양한 형태의 문서를 추가할 수 있다. 예를 들어 검색엔진의 복잡한 알고리즘을 별도로 설명한다던가, 관련 통계 자료를 제공할 수도 있을 것이다.

<리스트 1> NDoc 예제

/// <summary>
/// <para><paramref name="variable"/>가 빈 문자열인지 여부를 확인한다.</para>
/// </summary>
/// <param name="variable">
/// <para>확인할 값</para>
/// </param>
public static void CheckForEmptyString(string variable)
{
	CheckForNullReference(variable, variableName);
	if (variable.Length == 0)
	{
		throw new ArgumentException(SR.ExceptionEmptyString(""));
	}
}
	

더 나은 설계를 위하여

문서화 도구는 기본적으로 public/protected 클래스 및 메써드에 대해 주석을 달도록 권장하고 있다. Java나 C# 등의 컴파일러는 ? 적절한 옵션만 선택한다면 – 해당 구성요소에 주석이 없거나 일부 매개변수에 대한 설명이 빠져 있거나 하면 경고 또는 오류를 반환한다. 문서화 도구를 경험하지 못한 사람은 이러한 기능이 아무것도 아닌 듯 생각할 수도 있다. 그러나 필자의 경험에 따르면 그 이상이다.

이제는 객체지향개발이라는 것이 화두가 될 수 있는지 조차 의심스럽지만, 의외로 객체지향을 이해하는 개발자가 많지 않은 것도 사실이다. 이해할 만 하면 관리직으로 진출하게 되니 숙련된 개발자가 많지 않다. 그래서 2년 전의 필자와 같은 초급 개발자의 비중이 크기 마련이다. 객체지향개발에 익숙하지 못한 프로그래머는 클래스와 객체지향을 동일한 것으로 취급하기 쉽다.

이들이 저지르는 또 다른 실수는 클래스든 메써드든 public으로 선언해버린다는 점이다. 접근제한이라는 문제를 고려하지 않는다. 경험이 없는 개발자에겐 어떤 메써드를 public, protected, 또는 private으로 선언할 것인지 결정하는 것이 결코 쉽지 않다. 그렇게 한참 고민하고 나면 에라, 모르겠다. 그냥 전부 공개해버리자.라는 생각이 들게 마련이다.

이와는 정반대의 실수를 저지르기도 한다. 객체지향의 매력에 푹 빠진 나머지, 범용으로 재사용할 수 있는 멋진 설계를 해보자.라는 생각을 하는 경우도 있다. 의욕이 넘친 나머지 과도한 설계의 유혹에 빠져 버린다. 그러다 보면 업무에 부여된 한정된 시간을 훌쩍 넘기기 마련이다. 운 좋게 제 시간 안에 개발을 마쳤다고 생각해 보자. 좀더 융통성 있고 정교한 코드를 작성했으니 쾌재라도 부르고 싶을지 모른다. 그러나 해당 코드를 사용해야 하는 다른 개발자가 자유자재로 사용하거나 유지 보수할 수 있을 정도가 되려면 설계의 의미를 파악하는데 엄청난 시간을 투입해야 한다. 부끄러운 고백이지만 이것은 필자의 경험담이다.

문서 자동화 도구를 사용하는 환경에서는 이 문제에 대해 한번 더 고민하게 된다. 공개된 메써드가 많을수록 귀찮은 작업을 더 해야 한다. 당연하게도 이 메써드를 정말 공개할 필요가 있나?라고 재고하게 된다. 또한 여러 개의 공개된 메써드를 호출해야 하는 경우에는 인터페이스를 조금 더 간단하게 만들어서 공개된 메써드의 개수를 줄일 수는 없을까?라는 고민도 하게 된다. 한마디로 최소주의 원칙을 자연스럽게 습득해나가게 된다.

주석은 문서화의 일부일 뿐이다.

주석과 자동화 도구의 결합은 개발자가 설계에 대해 조금 더 고민하게 만들었다. 그러나 주석의 역할을 확대 해석하거나 맹신하면 역효과가 날 수 있다. 과유불급이라고 주석이 많으면 가독성이 떨어지고, 소스 코드에 집중할 수 없게 된다. 또한 지나친 주석은 올바르지 않은 의도의 산물일 수 있다. 『리팩토링』에서 마틴 파울러는 주석이 종종 탈취제로 사용된다.라고 말했다. 서투른 코드의 냄새를 감추기 위해 주석을 뿌려대는 꼴이다. 주석을 달 때는 다음과 같은 최소주의 원칙에 따라야 한다.

  • public 또는 protected 구성요소를 중심으로 주석을 달자. 이것은 자동화 도구의 기본값이다. 코드 작성자의 입장이 아닌 외부 개발자의 입장에서 보면 외부에서 접근할 수 없는 구성요소는 상대적으로 덜 중요하다. private을 포함한 모든 클래스, 멤버변수, 메써드에 주석을 다는 편집증적 태도는 도움이 되지 않는다.

  • 행동을 기술하자. 유지보수를 맡았거나 여러분이 개발한 컴포넌트를 사용하는 외부 개발자는 내부 구현에는 관심이 없다. C#에서 문자열 길이를 알고 싶다면 인스턴스 프로퍼티 Length를 호출하면 된다. 문자열의 길이를 멤버 변수에 저장해 놓았는지, 아니면 매번 재계산을 하는지 여부는 사용자의 입장에선 중요하지 않다. 그렇다고 내부 구현을 아예 언급하지 않는 것은 극단적인 선택이다. NetworkStream 객체는 Position이나 Length 호출을 지원하지 않는다는 사실이 MSDN 라이브러리에 적혀 있지 않다면, 많은 혼란을 초래할 것이다. 예외적이거나 매우 중요한 사실이라면 구현 방식을 언급하는 것이 당연하다.

  • 리팩토링과 디자인 패턴을 활용하자. 리팩토링이나 디자인패턴을 통해서 주석의 양을 줄일 수 있다. 기능이 무엇인지 도무지 알아볼 수 없는 DoWhatHaveToBeDone 메써드가 있다고 치자. 이때 rename 리팩토링을 해서 메써드의 이름을 ChangeCustomerName으로 바꾼다면, 주석으로 설명해야 하는 내용을 줄일 수 있다. 이번에는 오류 리포팅 서버를 개발한다고 생각해보자. 요구사항에 따르면 하나 이상의 서버 인스턴스가 작동하면 안 된다. 이런 경우라면 Singleton 구현을 활용하고, 클래스 이름을 ErrorReportingServerSingleton이라고 지어보자. 주석이 없어도 디자인패턴을 아는 개발자라면 이 클래스가 유일한 인스턴스를 제공한다는 것을 알 수 있다.

  • 자동 생성한 코드. C#에는 Type-safe Dataset이란 것이 있다. XML 스키마를 xsd.exe로 해석해서 Dataset의 파생 클래스를 생성한다. 이렇게 생성한 클래스는 족히 수백 개는 되는 public 또는 protected 클래스 등을 포함하는데, 이 모든 것에 주석을 달면 날 새는 것은 시간 문제다. 이런 경우에는 부모인 Dataset 클래스와 다른 점만 기술하면 된다. C# 개발자라면 Dataset이 무엇인지, 어떤 기능을 수행하는지 안다. 그러므로 중복설명을 피할 수 있다. 이것은 최소주의 원칙에도 부합한다.

추천 도서

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu