이전에 올렸던 리팩토링 스터디에 관한 포스팅은 곁들여서 들으면 좋을 이야기들을 위주로 포스팅하기 때문에, 본문의 내용을 따로 정리할만한 글이 필요하다고 느껴졌습니다. 2주차의 범위인 챕터 2~3의 본문 내용을 간략히 요약합니다. 스터디 정리는 리팩토링 스터디 #2 - 리팩토링 원칙 & 코드에서 나는 악취를 참고해주세요.
챕터 2의 제목은 리팩토링 원칙 입니다.
앞 장에서 여러가지 예시를 통해 대략적이나마 리팩토링이 어떤 과정을 거치는지 감을 잡으셨을 것이라 생각합니다. 이번 장에서는 리팩터링 전반에 적용되는 몇 가지 원칙들을 다룹니다. 이번 챕터를 읽고나서 챕터 1을 다시 보신다면 일련의 과정이 눈에 더 잘 들어오실 것 같습니다.
정의
으레 책들이 그렇듯, 용어의 정의부터 시작합니다. 저자는 리팩토링(refactoring)이라는 용어를 이렇게 정의합니다.
리팩터링: [명사] 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법
챕터 1에서 보았던 함수 추출하기, 조건부 로직을 다형성으로 바꾸기 등이 모두 이 정의에 해당하는 기법들입니다. 이 정의에 저자가 말하고자 하는 내용이 모두 담겨있습니다.
첫 번째, 소프트웨어의 겉보기 동작이 변하지 않을 것.
두 번째, (사람이) 코드를 이해하고 수정하기 쉽도록 내부를 변경할 것.
사실 앞으로 소개할 내용들은 이 두 가지의 중요성을 반복해서 강조하는 것이 전부라고 말해도 무방할 정도이기에, 유념해두시면 이해에 도움이 되실 것 같네요.
겉보기 동작(observable behavior)이라는 표현이 있습니다. 위의 첫 번째 강조문에서도 등장했었는데, 조금 더 설명을 하자면 여기서 말하는 '겉보기' 라는 단어는 어디까지나 이 프로그램을 사용하는 유저의 관점에서 바라봐야 한다는 의미입니다. 프로그램을 만드는 개발자들이 아닌 것이죠.
본문의 글을 인용하자면
"가령 함수 추출하기를 거치면 콜스택이 달라져서 성능이 변할 수 있다. 그렇다 해도 사용자 관점에서는 달라지는 점이 없어야 한다. (중략) 리팩터링 과정에서 발견된 버그는 리팩터링 후에도 그대로 남아 있어야 한다."
이렇게 표현할 정도로 개발자의 관점이 아닌, 이용자의 관점을 가져야 한다는 것이 중요하다는 뜻입니다.
리팩토링을 해야하는 이유
리팩토링이라는 것을 하면 좋다는건 알겠는데, 가뜩이나 개발하기도 부족한 시간을 쪼개가면서 해야할 필요가 있는지 같은 의문을 가져보신적 없으신가요? 저자는 그런 개발자를 위해 몇 가지 이유를 소개하였습니다.
- 리팩터링하면 소프트웨어의 설계가 좋아진다
소프트웨어를 처음 만들때, 어떤 방향으로 만들어야겠다는 목표나 설계를 정하고 시작하는 것은 흔한 일입니다. 하지만 이런 과정을 통해 정한 설계는 보통 본격적인 개발 시작과 동시에 점점 허물어져갑니다. 처음 의도했던 기능을 모두 구현한 뒤에는 새로운 기능 추가와 기존 기능 수정 등의 작업이 계속 일어나게 되는데 이 과정에서 아키텍처라고 부르는 소프트웨어의 내부 설계가 점점 썩게됩니다. (본문의 표현입니다)
특히 아키텍처를 충분히 이해하지 못한 채로 단기적인 목표 - 기능 구현 또는 로직 변경 - 만을 위해 코드를 수정하게 되면 처음 세웠던 기반 구조가 무너지기 쉽습니다. 이렇게 짜여진 코드들은 점점 설계를 파악하기 어렵게 변해가고, 잘못된 의도를 가진 코드들이 반복 생산되는 악순환의 고리에 들어오게 됩니다.
같은 일을 하더라도 설계가 나쁘면 코드의 길이는 길어지고, 알아보기 어려워지는 것은 충분히 납득되는 설명입니다. 물론 항상 비례하지는 않습니다만, 코드의 길이가 길어지면 수정하는데 드는 노력도 배로 증가하게 됩니다. 중복되는 코드의 제거가 설계 개선 작업의 중요한 축을 담당하는 이유이지요.
규칙적인 리팩토링 작업은 이러한 설계를 지탱해주는 중요한 역할을 합니다. 악순환의 고리를 끊고, 설계 개선에도 크게 기여합니다. 따라서 리팩토링은 소프트웨어의 설계에 긍정적인 영향을 미친다고 볼 수 있겠습니다.
- 리팩터링하면 소프트웨어를 이해하기 쉬워진다
소프트웨어 제작에서 협업의 중요성은 굳이 강조하지 않아도 아실거라고 생각합니다. 혼자서 개발의 0부터 100까지 모든 것을 책임지고 수행하는 자리가 아니라면, 이 코드를 읽고 함께 작업할 다른 개발자들을 배려하는 것은 필수입니다. 설령 1인 개발이라고 하더라도, 시간이 흐른 후 본인의 코드를 보았을때 모든 설계와 구조가 머릿속에 들어있을 것이라고 보장할 수는 없습니다. 결국 리팩토링 작업은 팀원 뿐 아니라 본인을 위한 길이기도 합니다.
컴퓨터야 아무리 복잡하게 쓰인 코드라도 어떻게든 이해하겠지만, 사람은 그렇지 않다는 것을 코딩을 할 때 항상 생각해야합니다.
- 리팩터링하면 버그를 쉽게 찾을 수 있다
위의 내용과 이어지는 내용인데, 이해하기 쉬운 코드는 버그를 찾기도 쉽습니다. 구조가 명확히 다듬어진 프로그램은 '이렇게 작동하지 않을까?' 라는 가정을 확신으로 바꿔주게 됩니다.
저자는 이 부분에서 켄트 벡의 이 말을 떠올린다고 합니다.
"난 뛰어난 프로그래머가 아니에요. 단지 뛰어난 습관을 지닌 괜찮은 프로그래머일 뿐이에요"
한 번에 멋진 코드를 만들어내는 능력보다는 쓰여진 초고를 퇴고하듯 하는 습관적인 리팩토링의 중요성을 강조한 말이겠지만, 개인적으로는 딱히 동의하지 못하겠다. ㅎㅎ
- 리팩터링하면 프로그래밍 속도를 높일 수 있다
지금까지 언급한 내용을 정리해보면, 결국 리팩토링을 하는 이유는 프로그래밍의 속도를 올릴 수 있기 때문입니다. 처음 저자의 설명을 듣고 코드의 품질을 올릴 수 있다는 점에는 쉽게 수긍하였으나, 전체적인 개발 속도가 올라간다는 부분에는 100% 동의하지 못하는 개발자가 많았다고 합니다.
한 시스템을 오래 개발중인 개발자들과 이야기를 하게되면, 초기에는 빠른 진척을 보이다가도 현재는 새 기능을 하나 추가하는 데에도 훨씬 오랜 시간이 걸린다는 말을 많이 한다고 합니다. 추가할 기능을 기존의 구성에 맞게 녹여내야하고, 그로 인해 생기는 버그도 해결해야하며 그 빈도는 시스템이 개발된 시간에 비례해 잦아진다는 것이 골조인데요.
이렇게 일정 규모 이상의, 소프트웨어를 지속적으로 개발해야한다면 결국 꾸준한 리팩토링을 통해 코드의 품질을 향상시키는 것이 전체적인 개발 시간으로 보았을때 훨씬 효율적인 작업이 된다고 합니다. 저자는 이를 설계 지구력 가설(Design Stamina Hypothesis)이라고 설명하네요.
리팩터링의 적기
그렇다면 리팩토링을 언제 하는 것이 좋을까? 라는 질문에 저자는 한 시간 간격으로 리팩터링을 한다고 답했습니다. 여전히 개인적으로는 과하지 않은가 라는 생각이 들지만 저자가 사용하는 몇 가지 패턴이 있어 소개하려 합니다.
저자는 돈 로버츠(Don Roberts)가 제시한 가이드에 따라
1. 처음에는 그냥 한다.
2. 비슷한 일을 두 번쨰로 하게 되면, 일단 계속 진행한다.
3. 비슷한 일을 세 번째 하게 되면 리팩터링한다.
위의 세 규칙을 3의 법칙이라고 부르는데 이 법칙을 어느정도 따라간다고 하네요.
지금까지의 이야기를 미루어보면 리팩터링을 적극적으로 권장하는 것처럼 들리는데, 리팩터링을 하면 안되는 상황도 있습니다.
지저분한 코드를 발견하더라도 굳이 수정할 필요가 없을 때인데요.
외부 API를 다루듯 호출해서 쓰는 코드라면 굳이 리팩토링하지 않습니다.
리팩토링은 내부 구조를 이해하고 사용해야 할 때 제대로 된 효과를 볼 수 있기 때문에 스쳐가듯 사용하는 코드에서는 시간적 낭비이고, 구조적 결함 등의 이유로 차라리 처음부터 새로 작성하는 게 쉬울 때도 마찬가지입니다.
어디까지나 리팩토링은 시간을 아껴주는 효율적인 도구일 뿐 그 자체가 목적이 되어서는 안된다는 점을 기억해야 할 것 같습니다.
마치며
챕터 2의 전반적인 내용 위주로 포스팅을 꾸려보았습니다. 이 정도라면 곧 작성하게 될 리팩토링 스터디 #2의 내용을 이해하는데 무리가 없을 것 같아요.
챕터 3의 내용은 리팩토링의 적기와 이어지는 내용이고, 일반적으로 어떤 코드들에 적용하면 좋은지에 대한 내용입니다. 이해보다는 제목만 보아도 알 수 있는 내용이라 굳이 본문에는 적지 않았습니다. (잘못 작성된 이름, 중복되는 코드, 길이가 너무 긴 함수 ... 등등 입니다.) 거기에 이 부분은 다음 포스팅에서도 한 번 더 언급될 일이 있을 것 같네요.
휘발성 메모리인 제 머릿 속 대신, 블로그라는 좋은 저장소에 넣었으니 오래도록 기억되었으면 좋겠습니다.
다음 포스팅에서 뵙겠습니다.
'기타' 카테고리의 다른 글
리팩토링 스터디 #2.5 - 내용 미리보기 (0) | 2020.09.26 |
---|---|
리팩토링 스터디 #2 - 리팩토링 원칙 & 코드에서 나는 악취 (2) | 2020.09.21 |
리팩토링 스터디 #1 - 첫 번째 예시 (4) | 2020.09.15 |
리팩토링 스터디 #0 - 스터디에 들어가며 (0) | 2020.09.14 |
CR / LF / CRLF - 줄바꿈 문자열 (0) | 2020.09.13 |
댓글