중복 코드

냄새 2. 중복 코드

  • 중복 코드의 단점
    • 비슷한지, 완전히 동일한 코드인지 주의 깊게 봐야한다.
    • 코드를 변경할 때, 동일한 모든 곳의 코드를 변경해야 한다.
  • 사용할 수 있는 리팩토링 기술
    • 동일한 코드를 여러 메소드에서 사용하는 경우, 함수 추출하기 (Extract Function)
    • 코드가 비슷하게 생겼지만 완전히 같지는 않은 경우, 코드 분리하기 (Slide Statements)
    • 여러 하위 클래스에 동일한 코드가 있다면, 메소드 올리기 (Pull Up Method)

리팩토링 4. 함수 추출하기

  • "의도"와 "구현" 분리하기
  • 무슨 일을 하는 코드인지 알아내려고 노력해야 하는 코드라면 해당 코드를 함수로 분리하고 함수 이름으로 "무슨 일을 하는지" 표현할 수 있다.
  • 한줄 짜리 메소드도 괜찮은가? -> 의도를 잘 드러낼 수 있다면 충분히 좋다.
  • 거대한 함수 안에 들어있는 주석은 추출한 함수를 찾는데 있어서 좋은 단서가 될 수 있다.
Note

메소드는 어떠한 행위에 이름을 정할 수 있다는 장점이 있다. 따라서 비록 한줄짜리 코드라도 읽는 사람의 입장에서 생각한다면 메소드 체이닝이 길거나 한눈에 들어오지 않는 경우에는 보다 명확하게 하기위해서 메소드로 추출해도 좋다.

Warning

‘한눈에 들어오는 코드블록의 단위’란 어느정도일까? 사실 이 부분은 매우 주관적이라서 정확하게 정하기가 어렵다. 그렇다면 내가 생각하기에는 ‘그 팀의, 혹은 그 회사 전체에서 가장 적은 경력의 주니어 개발자가 한눈에 이해할 수 있는 수준의 단위’ 정도로 미니멈을 잡는게 바람직하다고 생각한다. 왜냐하면 실무에서 신입의 입장에서 코드 읽고 파악하는데 한나절이 걸리고, 심지어 그 흐름에 대해서 잘못 파악하는 부분이 있을 수 있다. 따라서 여러모로 쉽게 읽을 수 있는 코드를 작성하는 것은 중요하다.

리팩토링 5. 코드 정리하기

  • 관련있는 코드끼리 묶여있어야 코드를 더 쉽게 이해할 수 있다.
  • 함수에서 사용할 변수를 상단에 미리 정의하기 보다는, 해당 변수를 사용하는 코드 바로 위에 선언하자.
  • 관련있는 코드끼리 묶은 다음, 함수 추출하기(Extract Function)를 사용해서 더 깔끔하게 분리할 수도 있다.

리팩토링 6. 메소드 올리기

  • 중복 코드는 당장은 잘 동작하더라도 미래에 버그를 만들어 낼 빌미를 제공한다.
    • 예) A에서 코드를 고치고, B에서 반영하지 않은 경우
  • 여러 하위 클래스에 동일한 코드가 있다면, 손쉽게 이 방법을 적용할 수 있다. 비슷하지만 일부 값만 다른 경우라면, "함수 매개변수화하기" 리팩토링을 적용한 이후에, 이 방법을 사용할 수 있다.
  • 하위 클래스에 있는 코드가 상위 클래스가 아닌 하위 클래스 기능에 의존하고 있다면 "필드 올리기"를 적용한 이후에 이 방법을 적용할 수 있다.
  • 두 메소드가 비슷한 절차를 따르고 있다면, "템플릿 메소드 패턴" 적용을 고려할 수 있다.
Tip

인텔리제이에서 메소드 우클릭 > Refactor > Pull Members Up 기능을 활용하면 상위 클래스로 “필드 올리기”를 적용할 수 있다.