[리팩터링] 1. 리팩터링 이해하기

안광의·2022년 9월 3일
0
post-thumbnail

반성하며

마지막으로 블로그에 포스팅을 한지 2달이 넘었다. 처음 블로그를 개설하고 나서 계속해서 꾸준히 글을 올리려고 노력했었는데 지난 2달 동안은 여러 이유로 소홀하게 되었다. 우선 이번 포스트 주제인 리팩터링에 대한 온라인 강의를 결제해서 공부를 했는데 강의 영상과 관련된 내용의 포스팅이 금지되어 있어서 공부하는 과정에서는 글을 올리지 못했고 백엔드 개발자분 한 분과 두명이서 사이드 프로젝트를 진행하다보니 블로깅을 할 여유가 없었다. 블로그를 메모장처럼 사용하기보다는 어느정도 완성도 있는 글을 작성하고 싶다보니 꽤 오랜 시간동안 글을 쓰지 못했던 것 같다. 앞으로는 예전과 비슷한 주기로 글을 쓸 수 있도록 노력할 예정이다.



시작하며

개발자로 일을 시작하고 나서 리팩터링에 대한 공부가 필요한 생각이 들었다. 아마 나처럼 경력이 짧은 개발자라면 내가 쓴 코드에 대한 확신이 들지 않을 것이다. 유저 입장에서는 동일하게 동작하는 서비스라고 하더라도 개발자에 따라서 작성된 코드의 퀄리티는 모두 다를 것이고 이 차이가 서비스를 유지보수하는데 쓰는 시간을 결정한다. 내가 오늘 작성한 코드는 다른 개발자가 이해하고 수정해야 할 코드가 될 수 있기 때문에 항상 친절하게 작성하려고 노력해야 한다. 코드 컨벤션 지키기, 함수 네이밍 잘짓기 정도의 기초적인 노력 이상으로 코드 퀄리티를 높이기 위한 공부가 절실하다고 생각해서 리팩토링 공부를 시작하였다.



리팩터링이란?

정의

리팩터링은 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법이다.

즉, 새로운 기능을 추가하거나 버그를 해결하는 것은 리팩터링이 아니다. 그러나 그 과정에서 리팩터링을 겸할 수 있고 그래야 한다. 새로운 기능으로 인해 기존에 사용하던 로직을 적용할 수 없다면 관련된 코드들을 더 적합하게 변경하는 리팩터링 과정을 거치면서 개발을 해야한다.

목적

아래는 책에서 기술하는 리팩터링의 장점이지만 결국 목적은 시간이다. 리팩터링에 쓰는 시간이 리팩터링을 하지 않아서 소모되는 시간보다 더 짧기 때문에 리팩터링하는 것이고 미래에 대한 투자이다.

  • 리팩터링하면 소프트웨어 설계가 좋아진다.
  • 리팩터링하면 소프트웨어를 이해하기 쉬워진다.
  • 리팩터링하면 버그를 쉽게 찾을 수 있다.
  • 리팩터링하면 프로그래밍 속도를 높일 수 있다.


코드에서 나는 악취

책에서는 리팩터링이 필요한 코드들이 가지고 있는 공통점들을 악취라고 표현하였는데 적절한 표현이라고 생각한다. 실제로 현업에서 '이걸 왜 이렇게?'라는 생각이 드는 코드를 발견하면 빨리 수정해놓고 싶다는 생각이 든다. 아래는 리팩터링이 필요한 악취들에 대한 정리이다.

기이한 이름

코드를 작성하면서 꽤 시간을 쓰는 부분이 네이밍이다. 깃헙에 비슷한 일을 수행하는 함수의 코드들을 찾아보기도 하고 기존에 같은 팀의 개발자가 작성한 코드를 참고하면서 이름을 정하는데 좋은 이름만으로도 다른 개발자 또는 미래의 내가 코드를 이해하는데 써야할 시간을 줄여준다. 또 이름을 정하기 어렵다면 애초에 너무 많은 기능을 담고 있는 잘못된 함수일 가능성이 있다.

중복코드

똑같은 코드가 반복된다면 하나로 통합하여 더 나은 프로그램을 만들 수 있다. 이는 앞으로 동일한 코드를 사용해야 할 때에도 유용하고 공통된 로직을 수정해야 할때도 유용하다. 한 곳만 수정하면 모든 곳에 적용되니 시간도 줄고 실수도 줄일 수 있다.

긴 함수

긴 함수는 코드를 이해하는데 시간이 오래 걸리기 때문에 짧은 함수로 분리해서 구현하는 것이 좋다. 실제로 회사에서 사용하는 린트 규칙 중에 함수 길이에 대한 제한이 있다.

긴 매개 변수 목록

함수의 매개변수는 없는 것이 제일 좋고 필요하다면 2개가 최대라고 책에서 기술되어 있다. 예외 상황이 있을 수 있지만, 동의하고 실제로 함수를 작성할 때도 매개변수를 최소화하려고 노력하다보면 자연스럽게 더 나은 코드를 작성하게 된다.

전역 데이터/가변 데이터

전역 데이터, 가변 데이터 모두 버그를 유발하기 쉬운 요소이기 때문에 사용을 제한하고 접근 범위를 최소로 줄여야 한다. 프론트엔드보다는 백엔드에서 더 중요한 부분이라고 생각한다.

뒤엉킨 변경/산탄총 수술

코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만 수정할 수 있기를 바라는데 한 곳의 수정으로 인해 다른 여러 곳을 변경해야 한다면 이는 뒤엉킨 변경이나 산탄총 수술이 발생한 것이다. 뒤엉킨 변경은 분리해야할 코드들이 한 곳에 섞여 있는 경우이고 산탄총 수술은 한 곳에 있어야 할 코드가 여러 곳에 흩뿌려져 있는 경우로 반대의 개념이다. 그렇기 때문에 해결법도 반대이다.

뒤엉킨 변경 산탄총 수술
원인 맥락을 잘 구분하지 못함
해법(원리) 맥락을 명확히 구분
발생 과정(현상) 한 코드에 섞여들어감 여러 코드에 흩뿌려짐
해법(실제 행동) 맥락별로 분리 맥락별로 모음

기능 편애

프로그램을 모듈화할 때에네는 코드를 여러 영역으로 나눈뒤 영역 안에서 이뤄지는 상호작용은 최대한 늘리고 영역 사이에서 이뤄지는 상호작용은 최소로 줄이는 데 주력한다. 기능 편애는 어떤 함수가 자기가 속한 모듈의 함수나 데이터보다 다른 모듈의 함수나 데이터와 상호작용할 일이 많을 때 발생한다.

기본형 집착

전화번를 단순히 문자 집합으로만 표현하기 보다는 일관된 규칙을 가진 데이터는 딱 맞는 타입을 직접 정의하는 것이 좋다.

반복되는 switch문

중복된 switch 문이 문제가 되는 이유는 조건절을 하나 추가할 때마다 다른 switch문들도 모두 찾아서 함께 수정해야 하기 때문이다.

반복문

반복되는 로직이 악취가 아니라 반복문을 사용해서 구현한 것이 문제이다. 자바스크립트의 경우 .map과 같은 메서드를 사용해서 파이프라인으로 바꾸는 것이 가독성과 유지보수에 좋다.

추측성 일반화

초보 개발자가 흔히 하는 실수라고 생각되는데, '나중에 필요할 거야'라는 생각으로 작성한 당장은 필요 없는 코드들이 이에 해당한다. 미래가 아닌 현재 상황에서 최적인 코드가 좋은 코드이고 추후에 상황에 맞게 리팩토링하는 것이 맞다.

중개자

객체의 대표적인 기능 중 하나로 외부로부터 세부사항을 숨겨주는 캡슐화가 있고 이 과정에서 위임이 자주 활용된다. 그러나 클래스가 제공하는 메서드 중 절반이 다른 클래스에 구현을 위임하고 있다면 문제가 되므로 중개자 제거하기를 통해 리팩터링 해야 한다.

거대한 클래스

함수와 마찬가지로, 한 클래스에서 너무 많은 일을 하려다 보면 필드 수가 상당히 늘어나고 중복 코드가 생기기 쉽기 때문에 슈퍼클래스 추출하기, 타입 코드를 서브클래스로 바꾸기 등 여러 기법으로 클래스를 분리하여야 한다.

데이터 클래스

데이터 클래스란 데이터 필드와 게터/세터 메서드로만 구성된 클래스를 말하는데 데이터를 저장 용도로만 쓰아다 보니 다른 클래스가 너무 깊이까지 함부로 다룰 때가 많다.

상속 포기

상속 포기는 서브클래스가 부모의 동작은 필요로 하지만 인터페이스는 따르고 싶지 않을 때 발생하는데 서브클래스를 위임으로 바꾸기나 슈퍼 클래스를 위임으로 바꾸기를 활용해서 상속 메커니즘에서 벗어날 수 있는 방법을 고민해야 한다.

주석

주석에 대해서는 의견이 분분한데 나는 책에 내용처럼 주석은 악취 중의 하나라는 의견에 동의한다. 실제로 일을 할때에도 주석을 사용한 적이 없었고 추가적인 설명이 불가피한 경우에는 별도의 문서로 작성하였다. 주석이 필요하다고 생각된다면 가장 먼저 주석이 필요없는 코드로 리팩터링 하는 과정을 거쳐야 한다.



마치며

코딩을 처음 배우고 사이드 프로젝트를 할때에는 리팩터링에 대한 이해가 부족했고 모두 처음 시작하는 프로젝트이기 때문에 정상적으로 기능이 동작하게 하는데 집중할 수 밖에 없었다. 또한 지속적으로 유지보수 하는 것이 아닌 짧은 시간에 결과물을 내기 위한 프로젝트이기 때문에 코드의 퀄리티는 떨어질 수 밖에 없었다. 취업을 하고 서비스를 유지보수하고 다른 개발자가 작성한 코드를 보면서 리팩토링에 대한 공부는 필수적이라고 생각했다.
리팩토링 공부가 기존에 있는 코드를 수정한다는 의미이고 기존 코드의 기능을 유지하면서 코드를 변경하는 기법에 대해 초점이 맞춰져 있지만 애초에 어떤 코드가 좋은 코드인지 판단해서 작성하는 역량을 기르는데 도움이 된다.

profile
개발자로 성장하기

0개의 댓글