티스토리 뷰

규칙 1: 메서드당 들여쓰기 한 번

어디서 시작할지 몰라 덩치크고 오래된 메서드를 노려보고 있다면? 거대한 메서드는 응집력이 떨어진다. 한 지침은 메서드 길이는 5줄로 제한하는 것이지만, 그런 종류의 이전(transition)은 코드가 500줄짜리 괴물들로 어질러져 있으면 의욕이 꺾이기 쉽다. 대신, 각 메서드가 정확히 한 가지 일을 하는지, 즉 메서드당 하나의 제어 구조나 하나의 문장 단락(block)으로 되어 있는지를 지키려고 노력한다. 한 메서드 안에 중첩된 제어구조가 있다면 다단계의 추상화를 코드로 짠 것이며, 고로 한 가지 이상의 일을 하고 있다는 뜻이다.

정확히 한 가지 일을 하는 메서드들로 작업을 하면 코드가 달라지기 시작한다. 애플리케이션의 각 단위가 더 작아짐에 따라 재사용의 수준은 기하급수적으로 상승하기 시작한다. 100줄로 구현된 5가지 작업을 맡은 하나의 메서드 안에서 재사용의 가능성을 골라내기란 어려울 수 있다. 주어진 컨텍스트에서 단일 객체의 상태를 관리하는 3줄짜리 메서드라면 많은 다양한 컨텍스트에서 쓸 수 있다.

예를 들어 아래와 같이 통합개발환경(IDE)의 메서드 추출(Extract Method) 기능을 써서 메서드에 들여쓰기가 1단계만 남을 때까지 동작 코드를 뽑아낸다.

class Board {
   ...
   String board() {
      StringBuffer buf = new StringBuffer();
      for (int i = 0; i < 10; i++) {
         for (int j = 0; j < 10; j++)
            buf.append(data[i][j]);
         buf.append("\n");
      }
      return buf.toString();
   }
}
class Board {
   ...
   String board() {
      StringBuffer buf = new StringBuffer();
      collectRows(buf);
      return buf.toString();
   }
 
   void collectRows(StringBuffer buf) {
      for (int i = 0; i < 10; i++)
         collectRow(buf, i);
   }
 
   void collectRow(StringBuffer buf, int row) {
      for (int i = 0; i < 10; i++)
         buf.append(data[row][i]);
      buf.append("\n");
   }
}

이 리팩터링으로 다른 효과도 발생한다는 사실에 주목하자. 각 메서드는 구현을 이름에 맞추다 보니 사실상 평이해졌다. 이렇게 더 적어진 코드에서 버그의 존재를 판별하기란 대체로 훨씬 쉽다.

첫 규칙의 마무리인 이 시점에서 반드시 언급하고 싶은 점은 규칙을 적용하는 연습을 많이 할수록, 더 많은 결실을 거두게 된다는 점이다. 처음 여기에 소개된 방식으로 문제를 분해하다 보면 매우 어색하게 느껴지고 별로 얻는 게 없다고 생각할 수도 있다. 하지만, 규칙을 적용하는 데도 기술이 있으며, 이는 프로그래머의 솜씨를 한 차원 높여준다.


이 규칙을 적용함으로써 자연스럽게 메서드가 SRP(Single Responsibility Princple)를 지킬 수 있도록 해주며, 메서드의 크기가 작아짐에 따라 재사용성도 증가하게 되고, 버그 찾기도 쉬워지게 된다.  

 

[출처]

developerfarm.wordpress.com/2012/01/26/object_calisthenics_2/

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함