brunch

You can make anything
by writing

C.S.Lewis

by HJ Jun 19. 2022

리팩토링

엄마~ 저 코드에서 구린 냄새나~

리팩토링이 뭔데 씹덕아

 엔트로피의 법칙을 아시나요? 항상 복잡한 상태로 나아간다는 자연계의 법칙입니다. 아마 프로그래밍은 자연계가 아니라고 생각하는데, 귀신같이 이 법칙이 들어맞는 것을 보니 소름이 돋기도 합니다. 리팩토링은 이 복잡한 상태로 나아간 코드를 다시 복잡하지 않은 상태로 끌어내리는 과정입니다. 


 물론 리팩토링은 프로그래밍의 영역에서만 존재하는 단어는 아니라고 생각합니다. 어떤 복잡한 상태를 유지 가능하도록 만드는 모든 과정이 리팩토링이라고 볼 수 있죠. 


나름 큰 결심

제가 겟차에 와서 가장 먼저 해야겠다고 생각한 작업은 리팩토링입니다. UI 버그나 에러처리 등 해야 할 작업이 산더미였지만, 리팩토링부터 해야겠다고 생각한 이유는 마치 엄청나게 커져버려 안에 뭐가 들어있는지 도무지 알 수 없는 덩어리에 작은 덩어리를 붙히는 방식으로 개발을 하고 있다고 느껴서입니다.

실용주의 프로그래머라는 책에서 이런 말이 나옵니다.

개발비용은 생산비용 + 유지비용이다.


대부분의 회사에서 개발비용을 산정할 때, 즉 어떤 서비스에 대해 개발자 숫자와 기간을 책정할 때 유지비용은 쏙 빼놓는 경우가 많습니다. 회사 입장은 이렇죠. 뚝딱뚝딱 화면을 찍어내고 API 붙히면 되는거 아니냐? 안타깝게도 맞습니다. 생산비용만 따지고 보면 그렇죠. 뇌빼고 개발하면 가능합니다.


 하지만 이렇게 하면 유지비용이 늘어납니다. 만든거 또만들고, 재사용 불가능한 구조가 되버려요. 조금이라도 새로운 UI를 요구하거나 수정사항이 생기면 다시 만들어야하고, 그 과정에서 수많은 사이드이펙트가 발생합니다.


 그리고 그렇게 할꺼면, 인하우스 개발자를 둘 이유가 있나요. 그냥 다 외주 맡겨버리면 잡음도 없고 편할테니까요.


그럼, 방을 정리해봅시다.

저는 흔히 리팩토링을 방정리와 비교하곤 합니다. 집에서 생활하며 우리는 항상 여러가지 물건을 사용하고, 새로 구매하고, 놔두죠. 이 과정에서 집이 정리되어있느냐 어지럽혀져 있느냐는 시간, 돈, 생각하는 비용 등 효율성의 측면에서 많은 차이가 납니다.


정리되지 않은 방과 리팩토링되지 않은 코드는 다음과 같은 공통점이 있습니다.   

방을 치우지 않아도 사는데 별 문제 없긴하다.

하지만 물건을 치우지 않아서 새로운 물건을 사면 어디다 둬야할지 모른다.

방이 너저분해서 뭐가 어딨는지 모른다. 필요하면 일단 그 때 다이소에서 사온다.

따로 모아두지 않아서 필요한 물건을 빠르게 찾을 수 없다. (그 집에 오래 거주한 사람이 아니라면 더더욱 그렇다)

규칙이 없으니 이런 사실을 알아차리는데도 오래걸린다.


 혼자 살고 있다면 이러한 점을 감안하고 그때그때 처리해도 뭐 불편하긴 해도 괜찮을텐데, 문제는 우리와 함께하는 사람들은 그렇게 생각하지 않을 것이라는 점입니다. 좋다 or 싫다의 문제가 아니라 그 때부턴 명확히 효율비용 문제니까요.


 물론 집을 항상 완벽하게 유지할 순 없습니다. 당장 급한 일이 있어 잠시 물건을 옮겨둘 수 있고, 살펴볼 여력이 없어서 있는 물건을 또 구매하기도 하겠죠. 하지만 여유가 되면 부지런히 원상복귀 시켜야합니다. 


정리 과정

과정은 복잡할 수 밖에 없습니다. 프로젝트 복잡도와 크기에 따라 새로 만드는게 빠를 수도 있죠. 또한 추가적인 시간을 써야하기 어떻게 생각해보면 안써도 될 절대적인 시간을 소비하고, 회사 일이라면 괜히 하지 않아도 될 일에 시간을 쓰고 괜히 했다가 오동작을 할까봐 눈치가 보일 수도 있습니다. 


 마치 아래 비둘기 헬리콥터의 회전하는 목을 정지시키고 날개를 작동시켜야 하는 과정을 진행하면서 이 과정에서 비둘기 헬리콥터는 전과 다름없는 속도 및 안정성으로 계속 날고 있다는 사실을 보장해야 하니까요.

아니 호준씨, 비둘기 잘 날아가는데 뭐가 문제에요?

가이드

청소에도 가이드가 필요합니다. 가령 다음과 같은 청소 규칙이 있다고 가정해봅시다.   

개인물품은 구역 A에 두고, 자주 쓰는 물품들은 구역 B에 둔다.

목적에 따라 a,b,c …으로 소구역을 정하고 목적성에 맞게 분류한다.

어떤 구역은 빗자루질만 하고 어떤 구역은 물청소까지 한다.

한번에 여러가지 일을 할 수 있는 물품은 한가지만 하도록 분리한다.


진짜 청소를 잘하지만 항상 결과물이 랜덤인 로봇을 사용할 이유가 있을까요? 청소하나는 기가 막히게 잘 하지만, 가이드라인이 없어서 청소 전과 후가 너무 이질적이거나 더 불편해진다면 할 이유가 없습니다.


그래서 미리 어떻게 변하게 될지에 대해 충분한 논의가 필요합니다. 이 과정에서 중요한 점은 모두가 문제를 인식하고 변화에 동의해야하며, 변화한 후 어떤 이점을 가질 수 있을 지에 대한 합의입니다.


리팩토링도 똑같습니다. 구성원이 합의한 어떤 규칙에 따라, 구조에 대해 합의하고 스타일에 대한 규칙을 정한 뒤 그에 맞게 코드를 변경하는 작업이 필요합니다. 폴더 구조부터 변수 이름까지, 컨벤션이라고 하는 규칙 정의 문서를 만들고, 이를 준수하려는 합의죠.


종속성

종속성은 삼국지의 적벽대전을 떠올리면 이해하기 쉽습니다.

조조는 배들을 단단한 쇠사슬로 이어 마치 평지에서 전투하는 듯한 편안함을 구현했습니다. 불이 나면 최악의 경우가 생길 것이라는 사실을 알았지만, 바람이라는 환경변수를 생각해보니 절대 그러지 않을 것 같아 묶어버렸죠.

배들을 쇠사슬로 묶어놔서 흔들림이 없다.

하지만 바람이 동남풍으로 변하는 기상천외한 상황이 발생한 것입니다. 한 척, 두 척 불이 붙기 시작하더니, 쇠사슬로 묶인 모든 전함에 불이 붙어 침몰하고 말았습니다.

배들을 묶어놔서 한번에 다 타버린 모습이다.

 서비스 개발의 관점에서 이처럼 견고하게 잘 엮인 모듈들은 유기적으로 동작하여 서비스에 안정성을 더합니다. 잘 만들어진 모듈을 하나 둘 만들다보면 굉장히 든든하기까지 합니다. 


 하지만 동남풍과 같이 생각지도 못한 환경의 변화설계 결함이 발생할 경우 주변에 미치는 영향이 어마어마합니다. 또한 낮은 수준의 모듈을 수정해야할 경우 간단한 수정이더라도 이 모듈을 종속성으로 가진 고수준 모듈들을 전부 테스트해야하는 문제도 있습니다. 그래서 이에 대한 의존성의 정도를 꼭 정해야합니다. 그리고 리팩토링 단계에서 그 의존성을 줄이거나 높힐 필요가 있습니다.


 정리를 마치고

 이런 좋은 취지로 시간까지 할애해가며 정리를 마쳤을 때 꼭 체크해야 할 사항이 있습니다. 정리라 함은 이전과 다름없지만 보기 좋고, 유지 가능해진 상태를 말합니다. 그래서 전과 후가 100% 동일한 기능을 하고 있는지를 체크하는 것이 중요합니다.


 청소의 경우 그런 점을 발견하기 힘들 수 있는데 리팩토링의 경우엔 다양한 테스트 환경에서 이를 테스트해볼 수 있습니다. 간단하게는 테스트 코드를 심을 수도 있고, UI 레벨까지 테스트를 할 수 있는 테스트 자동화 툴을 사용할 수도 있습니다.


 그렇게 합의된 가이드대로 작업을 마치고, 전과 동일한 동작을 성능의 저하 없이 동작함까지 보장받았다면 이제 그 가이드대로 살아가면 됩니다.



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari