최근에 회사의 팀원들과 책 스터디를 마무리했습니다. 꽤 오랜만에 진행한 스터디였는데요, 마지막으로 스터디했던 책이 작년 말에 읽었던 『프로그래머의 뇌』 였으니… 거의 반 년만에 진행한 스터디였군요.
이번에 읽은 책은 『파이브 라인스 오브 코드(Five Lines of Code)』 였습니다. 제목에서 짐작할 수 있듯이 이 책은 모든 메서드를 5줄 이하로 구현하라 와 같은 리팩토링 규칙을 제시하고, 이를 실제 코드에 적용하는 방법을 다루고 있습니다.
사실 이 규칙 말고도 다른 규칙들이 여러 개 있는데 아무래도 자극적이면서 독자들에게 임팩트를 주기 위해 책 제목을 이렇게 짓지 않았나 생각이 드네요. 저 역시도 책 제목을 보자마자 ‘아니, 어떻게 그게 가능해?’, ‘근데 왜 다섯 줄이지?’ 라는 호기심이 들었거든요. 팀 내에서 스터디를 진행한 목적도 이 책을 통해 팀의 문화로 적용할 만한 리팩토링 원칙을 찾을 수 있을 것 같다는 희망이 있었기 때문입니다.
책에서는 이러한 규칙들을 실습과 함께 다룰 뿐만 아니라, 리팩토링을 이루는 시스템과 문화에 대해서도 소개합니다. 그래서 오늘 포스트에서는 이에 대한 내용을 짧게 소개하고 느낀 점을 적는 식으로 마무리하려 합니다.
이번 포스트를 통해 리팩터링에 대한 규칙과 패턴에 대해 알아보고 싶은 개발자 분들께 도움이 되었으면 좋겠습니다.
책 소개
이 책은 『Five Lines of Code』의 번역본으로, 규칙과 패턴을 기반으로 객체지향 프로그래밍 방식에서 리팩토링을 어떻게 접근해야 하는지 를 다루고 있습니다.
기존 코드를 개선하는 것, 즉 리팩토링은 개발자가 맞닥뜨리는 가장 일반적인 작업 중 하나입니다. 다만 리팩토링에 대한 기준은 모호하고 주관적이기 때문에, 이 책에서는 리팩토링에 대한 접근법을 규칙과 패턴으로 제시합니다. 흔히 이야기하는 코드 스멜 또는 감각적 판단에 의존하기보다는 명확하고 실행 가능한 규칙을 알려주는 것이죠.
책 제목에서 언급한 것처럼 모든 메서드를 5줄 이하로 구현해야 한다는 규칙 설명에서부터 다양한 리팩토링 패턴, 주석에 대한 제안, 안전한 코드 개선 방법 등을 다루고 있습니다.
책은 크게 2부로 구성되어 있습니다. 1부는 리팩터링의 각 규칙을 소개하고 직접 리팩토링 실습을 진행하는 부분입니다. 2부는 좀 더 거시적인 관점에서 리팩토링을 다루는데, 코드 품질에 영향을 미치는 시스템과 스킬, 문화, 도구 등을 다룹니다.
책 분량은 368쪽으로 적당히 두꺼운 편입니다. 특히 1부의 경우에는 실습을 기반으로 모든 내용이 전달되기 때문에 실습을 함께 진행하면서 책을 읽는다면 완독까지 꽤 시간이 오래 걸릴 수 있습니다.
요약
책에서는 규칙 10개, 리팩터링 패턴 13개를 소개합니다.
규칙 10가지
- 다섯 줄 제한: 메서드는 사용하는 데이터 구조를 탐색하는 데 필요한 것보다 더 많은 코드로 구성돼서는 안 됨
- 호출 또는 전달, 한 가지만 할 것: 함수 내에서는 객체에 있는 메서드를 호출하거나 객체를 인자로 전달할 순 있지만 섞어 쓸 순 없음
if
문은 함수의 시작에만 배치:if
문이 있는 경우 해당if
문은 함수의 첫 번째 라인이어야 함if
문에서else
를 사용하지 말 것: 프로그램에서 이해하지 못하는 타입을 검사하지 않는 한 else 를 사용하지 않음switch
를 사용하지 말 것:default
케이스가 없고 모든case
에 반환값이 있는 경우가 아니라면switch
를 사용하지 않음- 인터페이스에서만 상속받을 것: 상속은 클래스나 추상 클래스가 아닌, 오직 인터페이스를 통해서만 받음
- 순수 조건 사용: 조건문의 조건식에서는 변수에 값을 할당하거나 예외를 발생시키거나 I/O와 상호작용해서는 안 됨
- 구현체가 하나뿐인 인터페이스를 만들지 말 것: 구현체가 하나뿐인 인터페이스를 사용하지 않음
- getter와 setter를 사용하지 말 것: 불리언이 아닌 필드에 getter, setter를 사용하지 않음
- 공통 접사를 사용하지 말 것: 코드에는 공통 접두사나 접미사가 있는 메서드나 변수가 없어야 함
리팩터링 패턴 13가지
- 메서드 추출: 한 메서드의 일부를 가져와 교유한 메서드로 추출함
- 클래스로 타입 코드 대체: 열겨형을 인터페이스로 변환하고 열겨형의 값을 클래스로 만듦
- 클래스로의 코드 이관: 기능을 클래스로 옮김
- 메서드의 인라인화: 프로그램의 가독성에 더 이상 도움을 주지 않는 메서드를 제거함
- 메서드 전문화: 메서드에서 불필요하고 문제가 있는 일반성을 제거함
- 삭제 후 컴파일하기: 인터페이스와 클래스의 전체 사용 범위를 알고 있는 경우, 사용하지 않는 메서드를 인터페이스와 클래스에서 제거함
- 유사 클래스 통합: 일련의 상수 메서드에서 서로 다른 두 개 이상의 클래스를 통합함
if
문 결합: 동일한if
문이 이어진 경우if
문의 분기를 결합하여 중복을 줄임- 전략 패턴의 도입:
if
문을 사용한 분기를 클래스로 인스턴스화하여 대체함- 구현에서 인터페이스 추출: 클래스에 대한 종속성을 인터페이스로 바꿈
- getter와 setter 제거하기: 기능을 데이터에 더 가깝게 옮겨 getter와 setter를 제거함
- 데이터 캡슐화: 변수와 관련된 불변속성(invariant)을 지역화하고 응집력을 명확히함
- 순서 강제화: 특정 순서대로 작업을 수행하는 것을 컴파일러가 보장하게 함
시스템과 도구, 문화
2부에서는 리팩토링의 관점을 코드 수준에서 벗어나 거시적인 관점에서 살펴봅니다. 크게 문화, 스킬 및 도구와 관련된 주제를 논의하는데 여기에는 컴파일러, 기능 토글, 칸반, 제약 이론 및 도구가 있습니다. 또한 코드 삭제와 추가, 훼손에 대한 접근 방식을 다루기도 하구요. 마지막으로 구조를 노출시키고 성능을 안전하게 최적화하는 구체적인 기술을 소개합니다.
책에서 다루는 철학
마지막으로 저자는 이 책에서 다루는 내용은 유용하지만 한 사람이 소화하기에는 너무 크다며, 아래의 기본 원칙을 내재화한다면 모든 세부적 원칙을 기억하지 않아도 혜택을 볼 수 있다며 글을 마무리합니다.
- 항상 더 작은 단계 찾기: 위험을 줄일 수 있으며 더 많은 유연성을 얻을 수 있음
- 기본 구조 찾기: 코드를 작성할 때 점토 덩어리를 천천히 성형해가며 내부 구조를 드러내는 조각가라고 생각하기
- 협업을 위한 규칙 사용: 규칙은 법이 아니라 도구이며, 이를 이용해 서로를 평가하지는 말기
- 개인보다 팀을 우선시하기: 코드를 빠르고 자신있게 변경해야 하므로 전체 코드 베이스에 방해가 되는 요소들을 제거해야 함
- 완전성보다 단순함 우선하기: 지나친 단순화는 문제가 되지만 정신적 능력을 초과하는 복잡성은 더 큰 문제가 됨
- 객체 또는 고차함수 사용하기: 객체와 고차함수는 사실 같은 개념이지만 팀에서 더 읽기 쉽다고 생각하는 것을 쓰기
후기
분명 좋은 책은 맞는데 왜 공감이 안 가지…
이 책의 장점은 명확한 규칙을 근거로 리팩토링하며, 리팩토링의 진행 과정을 아주 상세히 설명한다는 점입니다. 특히 1부에서는 거의 200쪽에 달하는 분량을 할애해 실습을 진행하며 적용 과정을 상세히 설명합니다. 리팩터링 자체를 처음 접하는 사람들에게는 요런 가이드가 도움이 될 것이라고 생각합니다.
또한 책 전체가 TypeScript로 작성되어 있어서, 프론트엔드 개발자가 읽기에도 언어적 부담이 적었습니다. 리팩토링을 다루는 책의 대부분이 Java 기반이다보니 프론트엔드 개발자에게는 공감하기 어려운 부분이 있었는데 요게 꽤 큰 장점이었습니다.
다만 이러한 장점과는 별개로… 이 책은 팀원들에게 그닥 좋은 평가를 듣진 못했고, 저도 솔직히 추천하기에는 애매한 책(…) 이라는 생각이 들었습니다. 크게 세 가지의 이유가 있었는데요.
우선 책의 내용이 객체지향 프로그래밍을 다루고 있다보니, 함수형 프로그래밍으로 패러다임을 전환한 개발자에게는 적용하기 어려운 부분이 많습니다. 저희같은 프론트엔드 개발에서는 함수형 사고를 더 많이 쓰는 경향이 있기 때문에, 이 책의 내용을 실제 코드에 적용하려 할 때 적용이 어려운 부분이 많았습니다. 특히 각종 if 문을 클래스로 대체하는 패턴, 전략 패턴을 쓰는 경우에는 이걸 업무 코드에서 어떻게 적용할지 감이 잘 안 잡히더라구요. 객체지향에서의 발버둥(?)들을 대부분 함수형 프로그래밍으로 해결 가능하다보니까 좀 공감이 안 가는 부분이 많았습니다.
또한 팀원들에게서 공통적으로 나온 의견 중 하나로, 리팩토링을 적용한 코드가 오히려 더 장황하고 어렵게 느껴지는 예시가 많았습니다. 실습 외에도 책에서 다양한 예제 코드를 제시하는데, 아… 이게 좀 공감이 안 가는 코드가 많았습니다. 오히려 오버 엔지니어링 같다는 느낌? 마치 장황한 Java 코드를 보는 것 같았습니다.
후반부의 내용은 소프트웨어 공학 수업을 듣는 듯한 추상적인 개념들 투성이었고… 이런 요소들 때문에 저희 팀이 스터디를 하면서 들이는 시간 대비 얻을 수 있는 지식의 가성비가 좋지 못해서 그랬던 것이 아닐까 그런 생각을 합니다. 다만 이것은 저희 팀에서의 상황이고, 만약 객체지향 프로그래밍을 적극적으로 활용하는 팀이라면 이 책이 꽤 훌륭한 가이드가 될 것 같다는 생각은 들었습니다.
즉, 책의 내용은 자세하지만 팀에서 추구하는 패러다임과 맞지 않아서 애매한 부분이 많았다 정도로 요약할 수 있을 것 같네요.