요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

#1-3 리팩터링 하지 마라

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

기획

대기업 실전 애자일 1장 #1-3 리팩터링 하지 마라

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

#1-3 리팩터링 하지 마라

 

* 혼자서 리팩터링 해보기

신입사원과 함께 해 본 짝 프로그래밍 실험이 끝났다. 이후 필자는 현장에서 더 많은 새로운 시도를 해보고 싶은 욕심이 생겼다. 내가 공부한 것을 현장에 적용할 수 있다는 흥분에 가슴이 뛰었다.

 

하지만 문제가 있었다. 내가 생각하는 시도들은 대부분 팀이 함께 해야 하는 것이었다. 필자는 새로운 시도를 함께 하자는 제안을 주변 동료들에게 할 수가 없었다. 난 팀의 막내였다. 주변 팀원들은 모두 필자보다 5년 이상 많은 사회 경험을 가지고 있었다. 실력도 경험도 출중한 인생 선배들에게 새로운 방식을 시도하자고 말하는 것 자체가 매우 어려웠다. 혹시나 내가 귀찮게 하여 주변 사람들이 나 때문에 힘들어져 나를 싫어하지 않을까도 걱정했던 것 같다.

 

고민 끝에 혼자 할 수 있는 것을 찾았다. 그것은 내 코드를 고치는 것이었다. 적어도 내가 담당하는 소스에 대해서는 내 결정으로 무언가를 시도하는 것이 가능했다. 내 코드는 내 소유였고 이를 수정하는 것도 나의 책임이었다. 그즈음 필자의 눈에 “리팩터링"이라는 기법이 눈에 들어왔다. 리팩터링은 '기능은 그대로이지만 코드의 설계를 개선하는 기법'이다.

 

“리팩터링은 누구에게 동의를 구할 필요도 없다!”

 

이때부터 나는 리팩터링을 수행할 사냥감을 찾기 시작했고, 가장 먼저 내 눈에 든 소스는 로그인 부분이었다.

 

[마틴 파울러의 리팩터링 카탈로그]

 

처음에 만들어진 로그인 코드는 단지 한 개의 클래스로 이루어져 있었다. 처음에는 라인 수도 적고 가독성도 그리 나쁘지 않았다.

 

하지만, 시간이 지나면서 이 코드의 복잡도는 기하급수적으로 증가하기 시작했다. 여러 업체가 참여하여 로그인 시 필수적으로 필요한 SSO, 보안 및 암호화 솔루션을 추가로 심으면서 코드는 점점 이상해져 갔다. (당시 이 전반적인 것을 컨트롤하여 업체들에게 코드 작성방법에 대해 가이드할 능력이 내게는 없었다.) 코드는 금세 여러 조각의 긴 클래스들로 바뀌었다. 또한 클래스 간 책임 분산도 이상하여, 서로 여러 번 호출하는 경우도 빈번했다. 결과적으로, 코드는 매우 너저분 해지기 시작했다. 전체를 알 수 없기에 수정할 수 없는 상황이 만들어졌다. 당시 필자의 생각으로는 코드를 정리하는 작업이 반드시 필요했다.

 

때문에, 나는 이 코드를 리팩터링 하기로 했다. 클래스를 분할하고 10 줄 이상되는 메서드는 추출하여 적절한 책임에 맞는 클래스에 매핑시켰다. 2,000 라인 이상 되던 코드는 클래스당 300~400 라인 정도씩으로 단순화되었다. 이 작없을 하는 동안 필자는 정말 즐거웠다. 수정한 코드가 그동안의 노력의 산물이고 결국 시스템에 훨씬 유익한 일이라 확신했다.

 

굳이 누구에게도 리팩터링 했다는 이야기를 하지 않았다. 사실 말할 필요가 없었다. “누가 이 엄청난 작업을 이해하겠는가?”라고 오만을 떨며 즐거워했다. 그리고 한 달간 리팩터링 한 코드를 배포했을 때, 나는 엔지니어로서의 짜릿함을 느꼈다.

 

 

* 리팩터링의 함정

하지만, 그 짜릿함은 오래가지 않았다. 새벽 1시에 배포된 소스코드는 다음날 아침 커다란 후 폭풍으로 밀려왔다. 필자가 아침에 출근하자마자, 필자의 사무실에 고객팀장이 와있는 것을 확인할 수 있었다. 고객팀장은 나의 프로젝트 관리자에게 화를 내고 있었다.

 

“무슨 일이 있는 거죠?”

 

"글쎄요. 저도 영문을 모르겠습니다. 테스트 잘했거든요."

 

프로젝트 관리자는 나를 보고 물었다.

 

“어제 무슨 일이 있었던 거냐? 왜 멀쩡하던 시스템이 오늘부터 안 되는 거야?”

 

"어? 글쎄요. 사실 굉장히 마이너 한 소스들만 배포했는데..."

 

난 본능적으로 영문을 모르는 듯 행동하며 상황을 확인했다. 당연히 어제 배포한 로그인 소스가 문제였다. 예상 못한 문제가 터졌다. 매일 시스템을 써야 하는 35만 사용자의 로그인이 안되고 있었다.

 

"!"

 

30분 정도의 상황 파악 후, 로그인 소스에 문제가 발생했다고 말했다. 고객은 처음에는 불같이 화를 냈다. 하지만, 복구 시간이 지연되면서, 고객의 얼굴이 점점 새 하얗게 질리기 시작했다. 또 다른 30분이 지나고, 그 고객은 나에게 어떻게든 이 상황을 제발 해결해달라고 간청하기에 이르렀다. 곧 누군가 징계를 받을 수 있는 상황까지 가고 있었다.

 

필자는 당장 고치기엔 시간이 없다고 판단하여, 이전의 소스로 다시 배포하기로 했다. 그리고 그 배포 후에 시스템 사용이 정상적으로 진행되는 것을 겨우 확인했다. 결과적으로 35만 명의 사용자가 3시간 동안 로그인을 하지 못했다. 신문에 날 사고를 필자가 만들어 낸 것이었다. 당시 나의 프로젝트 관리자는 이 일의 후속 조치로, 다시는 이 같은 일이 발생하지 않을 것이고, 만약 발생한다면 모든 책임을 지겠다는 각서까지 썼다.

 

난 이 상황이 정말로 이해가 되지 않았다. 개발환경에서 분명히 완벽하게 돌던 소스였다. 완벽했다. 무엇인가 이상했다. 그리고 억울했다. 한 달간 정말 완벽하게 수정했었다. 그런데 무엇이 문제였던 것일까?

 

사실 이유는 단순했다. 나는 필요한 테스트를 제대로 하지 않았다. 기존 레거시 시스템에서 한 달간 모듈을 수정할 때, 나는 모든 코드를 읽고, 이렇게 하면 되겠지 라는 본능으로 리팩터링을 했다.  나름 테스트를 했지만 견고하지 않았다. 수정할 때마다, 이전의 코드가 정상적으로 돌아가는지 또한 확인하지 않았다. 이전에 잘 돌아가는 것에 대한 회귀 테스트(Regression)를 제대로 하지 않았다. 리팩터링 카탈로그의 가이드대로, 이를 보완해 수 있는 자동화 테스트 코드를 먼저 짜 놨다면 어땠을까? 메서드를 아주 잘게 쪼개 역할별로 잘 나눌 때마다 이를 확인하면 어땠을까? 이 테스트 코드와 지속적인 통합 시스템을 함께 돌려 수정할 때마다 계속 기존의 기능을 조금씩 확인했다면 어땠을까?

 

문제가 발생할 조금의 가능성은 줄였을지도 모르지만, 여전히 유사한 문제는 발생했으리라는 것이 지금의 생각이다. 왜냐하면, 레거시 코드의 리팩터링을 하는 경우, 의존성이 있는 기존 코드가 정상적으로 동작하는 것을 확인할 수 있는 적절한 방법이 있어야 하는데, 특히나 내부의 로직이 많이 있는 형태의 코드의 경우 이것이 매우 어렵다.

 

모킹(Mocking)을 이용하는 방법이 있지만, 이것이 모든 문제를 해결할 수 있다는 가정도 기존 로직을 잘 알고 관련된 기능에 대해 화이트박스(Whitebox) 테스트를 할 수 있는 상황이어야 하고, 손으로 테스트를 하더라도, 블랙박스(Black box) 테스트를 할 수 있는 입력값과 결괏값에 대해 모든 상황을 알 수 있다는 가정이 있어야 한다. 이는 매우 매우 어려운 작업이다.

[테스트 커버러지 확인 모습]

 

2001년에 나온 “레거시 코드 활용 전략(Working Effectively With Legacy Code)”의 책의 작가 마이클 패더스는 위와 같은 이유 때문에 그의 저서에서 다음과 같이 언급했다.

 

“테스트들이 없는 코드는 나쁜 코드이다. 아무리 이것이 잘 쓰였다고 해도 말이다. 얼마나 예쁘게 객체지향으로 작성했던지, 캡슐화를 했던지와는 관계가 없다. 테스트가 있으면 우리는 코드의 행위를 빠르게 검증하며 고칠 수 있다. 이것이 없을 때 우리는 사실, 우리 코드가 더 나아지는지 나빠지는지 잘 알기 어렵다"

 

나는 이 위험한 실험과 배움을 통해 지속적인 통합과 자동화 테스트와 리팩터링의 중요한 상관관계에 대해 가슴 깊이 이해하기 시작했다. 리팩터링을 할 때에는 테스트 코드를 함께 짜는 것이 좋다. 그리고 한 개씩 리팩터링 할 때마다 테스트 코드를 지속적인 통합 시스템에 함께 실행하며, 다른 코드들이 온전히 동작하는지 확인하는 게 필요하다. 이 세 가지는 같이 동작하게 하는 게 가장 좋은 방식이다.

 

리팩터링은 정말 예민하고 실력이 요구되는 작업이다. 리팩터링을 그렇게 좋아했건만... 필자는 비슷한 방식으로 기존 코드가 엉망이라 이를 수정하려는 사람들에게 지속적인 통합과 테스트 코드 또는 충분한 도메인 지식 없이는 “리팩터링은 하지 말라"라고 말하기 시작했다.

좋아요

댓글

공유

공유

댓글 0
작가
0
명 알림 받는 중

작가 홈

작가
0
명 알림 받는 중
삼성SDS에서 지난 15년간 "애자일을 통한 지속적인 개선"을 주도해온 삼성의 Chief troublemaker 신황규입니다. '06년 삼성 최초로 SI 프로젝트에서 개발자로 스크럼과 XP를 적용하고 9년간 프로젝트 리더이면서 애자일 코치로 활동하다가 '15년 120명 규모의 Agile core team이라는 애자일 전문 코칭/개발 조직을 구성하고 3년간 조직 리더로 일했습니다. 현재는 새로운 도전을 위해 대기업 내에서 스타트업처럼 일하는 조직의 리더로 이동하여 비대면 협업툴 Marimba.team의 상품 디렉터로 일하고 있습니다.

좋아요

댓글

스크랩

공유

공유

지금 회원가입하고,
요즘IT가 PICK한 뉴스레터를 받아보세요!

회원가입하기
요즘IT의 멤버가 되어주세요! 요즘IT의 멤버가 되어주세요!
요즘IT의 멤버가 되어주세요!
모든 콘텐츠를 편하게 보고 스크랩해요.
모든 콘텐츠를 편하게 보고 스크랩 하기
매주 PICK한 콘텐츠를 뉴스레터로 받아요.
매주 PICK한 콘텐츠를 뉴스레터로 받기
로그인하고 무료로 사용하기