매개변수 3개는 너무 많은 것일까?

저는 책을 멀리하는 사람이기 때문에 Robert Cecil Martin이 Clean Code에서 이런 말을 했다는 것을 알지 못했습니다.

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification

전문이 아닌 짧은 구절만 읽어서는 정확한 의미를 파악할 수 없습니다. 그런데 얼마전 메서드 매개변수가 3개이면 코드를 이해하기 어렵기 때문에 나쁜 디자인이라는 주장을 직접 접하기도 했습니다. 정말 3개 이상의 매개변수를 가진 메서드는 나쁜 디자인일까요?

three

저는 그렇게 생각하지 않습니다. ‘3’이라는 수가 중요하다는 부분에 대해서 특히 동의할 수 없었습니다. 메서드 매개변수가 2개를 넘으면 나쁜 디자인이라는 규칙이 프로그래밍에 있어서 보편적으로 적용되어야 할, 혹은 적용될 수 있는 기준이라면 모든 경우에 대해서 증명되어야 합니다. 통계 계산 엔진이나 그래픽/ 기하 라이브러리를 만드는 프로그래메어게 이런 기준은 합리적으로 다가올까요?

F-분포는 자유도 2개를 가집니다. 자유도 2개와 통계량, 유의수준을 포함한 4개의 매개변수를 입력받는 F-검정 함수를 통계 라이브러리에 추가한다면 이것은 나쁜 디자인라고 결론지을 수 있을까요? C++의 <algorithm> 표준 라이브러리 함수들 상당수는 더 나은 디자인을 위해 매개변수 수를 줄여야 할까요? 아니면 문맥이나 플랫폼에 따라 달라질까요?

GDI+의 단순한 기능 중 하나인 Graphics 클래스의 DrawLine() 메서드 중 매개변수 수가 가장 적은 버전의 시그니처는 다음과 같습니다.

Status DrawLine(
  [in]       const Pen *pen,
  [in, ref]  const Point &pt1,
  [in, ref]  const Point &pt2
);

매개변수가 너무 많아서 이해하기 어려운가요? 저는 그렇지 않군요.

.NET의 System.String 클래스는 문자열의 특정 범위에서 지정한 비교 기준을 적용해 하위 문자열의 인덱스를 반환하는 IndexOf() 메서드를 가집니다.

public int IndexOf(
    string value,
    int startIndex,
    int count,
    StringComparison comparisonType
)

var s = "hello world";
s.IndexOf("WORLD", 5, 6, StringComparison.OrdinalIgnoreCase);

이 경우 count 매개변수는 클라이언트 코드 가독성을 떨어뜨립니다. 클라이언트 코드의 3번째 매개변수가 count를 의미하는지 endIndex를 의미하는지 혼동될 수 있기 때문이죠. 만약 startIndexcount 매개변수를 Range라는 형식으로 캡슐화하고 이를 입력받는 확장 메서드를 만들어 사용하면 코드를 이해하기가 좀 더 수월해질 것입니다.

사실 count 매개변수가 가독성을 많이 떨어뜨리지는 않습니다. endIndex일 수 있다고 고민할 필요가 별로 없는데, startIndex와 endIndex를 매개변수로 사용하면 빈 범위를 나타내기 곤란하거나 직관적이지 않게 되어서 좋은 디자인을 가진 코드에서는 사용되지 않기 때문이죠. 글의 전개를 위해 코드가 조금 더 분명한 의미를 나타내는 방법을 고려해 봅니다.

pubic struct Range
{
    public int StartIndex { get; set; }
    public int Count { get; set; }
}

public int IndexOf(
    this s,
    string value,
    Range range,
    StringComparison comparisonType
)

var s = "hello world";
var range = new Range { StartIndex = 5, Count = 6 };
s.IndexOf("WORLD", range, StringComparison.OrdinalIgnoreCase);

하지만 그래도 this 문맥을 제외한 매개변수의 수는 여전히 3개 이상입니다. ‘3’이라는 수 자체가 중요하다면 매개변수를 하나 더 줄일 방법을 고민해야합니다. 과연 이것이 생산적인 고민일까요?

비슷한 예를 하나 더 들어보죠. 직사각형을 나타내는 개체를 초기화하는 함수가 4개의 수를 입력받는 다면 (x1, y1, x2, y2)인지 (x, y, width, height)인지 혼동될 수 있습니다. 대신 (point, point)(point, size) 버전의 함수를 사용한다면 쉽게 읽혀질 것입니다.

매개변수를 재설계해 클라이언트 코드의 가독성을 높인 위 2개의 예에서 중요한 것은 숫자 ‘3’이 아니라 매개변수의 ‘설명력’이었습니다. ‘메서드를 디자인할 때 3개 이상의 매개변수가 사용되었다면 충분한 설명력을 가지는지 한 번 더 고민해보자’는 제안 수준의 지침이라면 받아들일 수 있습니다. 하지만 ‘3’이라는 수에 집착하는 것은 어리석은 행동입니다.

규칙은 가치를 만들어 낼 때 의미를 가집니다. 예를 들어 ‘높은 가독성’은 가치이고 ‘클래스 이름에 파스칼 표기법을 사용한다’는 가독성을 높이기 위한 규칙이죠. 가치를 망각한 채 규칙 목록을 늘리고 규칙 자체에 얽매여 비생산적인 비용 소비를 동료에게 강요하거나 타인의 코드를 심판하는 기준으로 삼는 것은 바람직하지 않습니다. 스스로의 훈련을 목적으로 혼자서 규칙을 남용해 보는 것, 혹은 개인의 취향과는 다른 얘기입니다.

Advertisements

매개변수 3개는 너무 많은 것일까?”에 대한 7개의 생각

  1. Seojey

    책을 읽어보시면 3개가 특별한 문제가 아니라 매개변수가 많음에서 오는 이슈입니다.
    3개여서가 아니라 3개나 필요한가 ? 가 더 맞겟군요.
    R Martin 은 특정 수 이야기하긴 했지만 책 전체에서 자신의 의견이 정답이라 이야기하진 않았습니다.
    다만 자산과 애자일 진영의 많은 개발자가 매개변수가 많아 지는 것에 이슈가
    있음을 이야기 하고 있군요.(저 역시 영어와 친하지는 않아 번역본의 내용입니다.)
    결국 중요한 건 클린 코드란 기능 뿐만 아니라 누구나 쉬운 구현을 위함입니다.
    3이란 상징적 숫자라 생각합니다. ^^
    저 역사 책에서 이야기한 “3개나 필요해?” 에 대해선 개취하고 생각하지만
    그 이유는 이해할 수 있었습니다.
    선배 개발자의 좋은 경험을 담은 책이니 간단히 의견을 다는 것 보단 해당 부분을 읽어 보심을
    추천드립니다.

    응답
    1. Gyuwon 글의 글쓴이

      원문을 다시 한 번 읽어보세요. 매개변수가 3개를 넘으면 아주 특별한 정당성이 필요하다고 한 부분에 특히 주목하세요.

      The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification

      제 글은 ‘Clean Code’라는 책이 좋은 책인지 나쁜 책인지, 혹은 ‘Clean Code’라는 것의 정의에 대해 말하고 있지 않습니다. 매개변수가 많아지는 것이 코드 품질에 전혀 영향을 주지 않는다고 주장하고 있지도 않습니다. 전체적인 맥락과 결론을 오해하고 계신 것이 아닌가 싶네요.

      응답
  2. seojey

    우선 책으로 보라고 말름 드린 이유는 변수가 많음이 (개발자간) 가독성을 떨어틀린단 의미였습니다. 즉 개인에 대한 가독성이 아니라 다양한 사람이 함께 개발함에 있어 여러 변수에 대해 이해도가 갖지 않음을 이야기 한것입니다.
    즉 아마도 r. martin이라면 indexiOf자체를 변수로 썻을 것입니다.
    생성시에 다양한 조합이 필요함은 누구나 아는 부분입니다. 그럼에도 변수을 제한하는 것이 좋다는 의미는 기능적인 부분이 아니라 상대방과의 이해도를 높이기 위함입니다.
    동알한 의미지만
    3개 이상은 그애 따른 특별한 의미가 필요하단 뜻은 뜻은 3개까지 가기 전에 다양한 방법으로 보가 높은 가독성을 얻을 수 있단 의미입니다.
    해당 내용은 단순히 변수의 많음을 이야기 한 것이 아니라
    책 내에서 어느 쪽이 더 clean 한가에 대한 의미 입니다.
    그래서 clean code란 관점에서 매개변수에 대한 갯수를 의미합니다.

    응답
    1. Gyuwon 글의 글쓴이

      우선 죄송하지만 말씀하시는 바를 정확히 파악하기 쉽지 않습니다. 여러군데 틀린 맞춤법도 ‘가독성’을 떨어뜨리고요,

      즉 아마도 r. martin이라면 indexiOf자체를 변수로 썻을 것입니다.

      생성시에 다양한 조합이 필요함은 누구나 아는 부분입니다.

      두 구절은 특히 여러 번 읽어봐도 이해하기 너무 어렵습니다. 그래서 동의나 반론제기가 쉽지 않네요.

      저는 글에서 매개변수 디자인을 통해 코드의 가독성을 높일 수 있다는 것을 설명했고 이것이 ‘3개 미만의 매개변수’라는 절대적인 잣대를 의미하는 것은 아니라는 애기를 했습니다. 저는 깨끗한(clean) 코드를 작성할 필요가 없다고 얘기하지 않았습니다. 오히려 ‘3개 미만의 매개변수’에 집착하면 깨끗하지 않은 코드를 작성하게 될 수도 있다는 점을 말씀드리고 있습니다. 사실 ‘3개 미만 매개변수론’을 주장하는 사람들 사이에서도 이미 예외 케이스들을 말하고 있습니다. 예를 들어 http://www.c2.com/cgi/wiki?TooManyParameters 에서는 불변개체 생성을 말하고 있죠.

      일단은 제 글을 다시 한 번 차근차근 읽어보시고 제가 무슨 말을 하고있는지 잘 파악해주시고요, 댓글을 작성할 때에는 ‘상대방과의 이해도를 높이기 위함’을 고려해주시면 감사하겠습니다.

      응답
  3. freeism

    책의 많은 부분에서 밝히고 있는 바에 따르면, 저자가 말하는 것은 ‘법칙’이 아니라 경험에 따른 ‘컨벤션’을 정리한 것입니다. 3이란 의미는 단순히 통계적으로 봤을 때, 매개변수가 3개가 넘어갈 경우 정말 필요한지 고민하거나 DTO를 사용하여 공통된 객체로 분리하길 고민해보라는 것이구요. 반드시 3개를 넘기면 안된다는 법칙을 얘기하지는 않습니다. 비슷한 일례로, 마틴파울러도 하나의 메소드에 5줄을 넘기면 안된다는 얘기를 했습니다. 5줄 미만으로만 코딩을 하라고 하지는 않았지만, 5줄이 넘어갈 경우 복합관심사가 있지는 않은지 한 번 생각해보라고 했습니다. 두 가지 케이스 모두, 스스로의 기준값을 가지고 기준을 넘어가면 다시 한 번 고민해보라는 의미로 저는 받아들였습니다.
    저도 관심이 많은 부분이라 지나가다가 댓글 남기고 갑니다. 블로그를 깔끔하게 잘 쓰시네요^^

    응답
    1. Gyuwon 글의 글쓴이

      의견 감사합니다. 본문에서 밝혔듯이 저는 해당 서적을 읽지 않았기 때문에 인용한 구절만으로는 엉클 밥의 의도를 정확히 파악했다고 할 수 없습니다. 그럼에도 이런 글을 작성한 이유는 Stack Overflow 등에서 ‘3’ 자체에 큰 의미를 두고 다른 사람의 코드를 단정적으로 나쁘다고 평가하는 사람들을 봤기 때문입니다. 코드 개선 여지에 대한 일종의 신호 정도로 해석하는 것은 기꺼이 받아들일 수 있습니다.

      응답
  4. mcautosite

    저도 책을 한번 읽어보라고 권하고싶습니다.
    책의 전반적인 주제가 책의 제목과 일치합니다.
    책을 읽지않고 하나의 항목에만 반박하는 글이라 다른 사람이 읽었을때 잘못된 생각을 가질 수 있을것 같아서 지나가다가 댓글 남겨봅니다!
    ‘자신이 쓴 코드를 다시보는 것 8할 코드를 작성하는것 2할 그렇기 때문에 코드를 읽기쉽게 짜는것은 중요하다.’ 가 주 내용인데 3개의 파라미터가 다시읽기에는 좋지 않고 더 좋은 방법이 있을 것이다는 내용이었던걸로 기억을 하고있습니다
    말씀하신대로 남의 코드를 3이라는 단어로 비판하는것은 당연히 좋지 않아보입니다
    애초에 비판이라는게 설득력이없으면 그건 비판이 아니라 매도겠지요
    하지만 개발자로서 성장(?)을 위해서라면 정말로 제대로 된 비판또한 필요하다고 생각합니다
    이야기가 샜지만 글을 잘쓰셔서 다른사람이 책을 읽지않고 부정적으로 인식할것같아서 조금 오지랖을…
    Clean Code 책 추천합니다 !

    응답

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중