실무에서 배운 것 #1. 중복 코드는 정말 나쁠까?

안녕하세요, 해을입니다🦖

이번에는 처음으로 실무를 하며 느끼고 배운 점을 기록해보려고 합니다.

그동안은 오류 해결이나 기술 정리 위주의 글을 주로 작성했는데, 실무를 하면서는 단순히 문제를 해결하는 것보다 ‘왜 이렇게 설계했는지’, ‘어떤 고민을 했는지’​가 더 기억에 남는 순간들이 많았습니다.

앞으로는 실무를 하며 제가 고민하고 배운 것들을 하나씩 기록해보려고 합니다😊

그 첫 번째 이야기는 ‘중복 코드’ 입니다.


🍀 중복 코드는 정말 나쁠까?

개발을 시작하고 가장 많이 들었던 말 중 하나가 있습니다.

“중복 코드는 제거해야 한다.”

저 역시 비슷한 기능이나 로직을 보면 자연스럽게 공통 함수로 분리하고, 하나의 파일에서 관리하는 것이 좋은 코드라고 생각했습니다.

코드를 한곳에서 관리하면 수정할 곳도 줄어들고, 같은 기능이 여러 파일에 반복되는 것도 막을 수 있기 때문입니다.

하지만 여러 사람이 거쳐 간 SI 프로젝트를 운영하면서,

“공통화된 코드가 앞으로도 정말 같은 책임을 가질 수 있을까?”

중복을 제거하는 것만큼이나 중요한 것이 있다는 사실을 조금씩 느끼게 되었습니다.

🍀 처음에는 편했던 하나의 파일 구조

제가 맡았던 프로젝트에는 비슷한 기능을 사용하는 회원가입과 마이페이지가 하나의 공통 훅을 사용하고 있었습니다.

두 화면에서는 공통으로 다음과 같은 정보를 입력했는데요.

  • 이메일
  • 주소
  • 그 외 추가 정보

프로젝트 구버전에서는 회원가입과 마이페이지 코드가 각각 나뉘어 있었고, 신버전에서는 두 화면의 로직을 하나의 파일이나 공통 훅에서 함께 처리하고 있었습니다.

처음 코드를 파악할 때는 신버전 구조가 훨씬 편했습니다.

회원가입과 마이페이지를 번갈아 보려고 여러 파일을 이동할 필요도 없었고, 한 파일만 보면 두 화면의 전체적인 흐름을 한 번에 파악할 수 있었기 때문입니다.

특히 여러 개발자가 함께 작업했던 SI 프로젝트 특성상, 관련 로직이 이곳저곳 흩어져 있는 것보다 하나로 모여 있는 편이 훨씬 읽기 편했습니다.

🍀 비슷한 듯 달랐던 두 개의 화면

처음에는 비슷해 보였지만, 서서히 두 화면의 차이가 드러나기 시작했습니다.

예를 들어

  • 회원가입에서는 기존 정보를 조회할 필요가 없지만
  • 마이페이지에서는 기존 정보를 조회해 화면에 표시해야 했습니다.

또 다른 기능은

  • 회원가입에서는 단순히 입력을 건너뛰는 의미였고
  • 마이페이지에서는 기존 정보를 삭제하는 의미였습니다.

겉으로 보기에는 비슷한 화면이었지만, 실제로는 서로 다른 목적을 가진 기능이었습니다.

이 차이를 제대로 분리하지 않아 회원가입에서 건너뛰기를 눌렀을 뿐인데 삭제 API가 호출되는 것처럼, 화면의 목적과 맞지 않는 동작이 발생하기도 했습니다.

결국 공통 로직 안에는 자연스럽게 이런 코드가 늘어나기 시작했습니다.

if (pageType === 'signUp') {
  ...
}

if (pageType === 'myPage') {
  ...
}

처음에는 간단한 조건 하나였지만, 화면별 요구사항이 늘어날수록 분기도 함께 많아졌습니다.

중복을 줄이기 위해 합친 코드가 점점 더 많은 예외 상황을 품게 된 것입니다.

🍀 한 파일에 있다고 항상 읽기 쉬운 것은 아니었다.

처음 프로젝트를 분석할 때는 한 파일에 있는 것이 분명 편했습니다.

하지만 요구사항이 계속 달라지기 시작하자 장점이었던 구조가 오히려 단점처럼 느껴졌습니다.

회원가입 기능을 수정하려고 파일을 열었는데 마이페이지 로직도 함께 읽어야 했고, 반대로 마이페이지를 수정할 때도 회원가입 분기를 함께 신경 써야 했습니다.

결국 하나의 파일을 수정할 때마다 다른 화면에 영향을 주지 않을지 계속 고민하며 사이드 이펙트를 확인해야 했습니다.

그때 처음으로 코드가 한곳에 모여 있는 것과, 코드가 읽기 쉬운 것은 다른 문제​라는 것을 느꼈습니다.

공통화로 파일 수는 줄었지만, 파일 안에서 이해해야 할 맥락은 오히려 늘어난 셈이었습니다.

🍀 커밋 이력에서도 드러나는 장단점

이 차이는 코드를 읽을 때 뿐만 아니라 커밋 이력을 확인할 때도 느껴졌습니다.

구버전에서는 회원가입과 마이페이지 파일이 분리되어 있었습니다.

useSignUpEmailInput.js
useMyPageEmailInput.js

그래서 수정된 파일명만 보더라도 대략적인 작업 범위를 알 수 있었습니다.

반면 신버전에서는 두 화면이 같은 파일을 사용하고 있었고,

useEmailInput.js

커밋 목록에서 이 파일만 수정된 것을 보고서는 어느 화면의 변경인지 바로 파악하기 어려웠습니다.

커밋 메시지가 충분히 구체적이지 않다면 결국 코드를 직접 열어 변경 내용을 확인해야 했습니다.

물론 파일을 분리한다고 해서 모든 이력이 자동으로 명확해지는 것은 아니지만, 파일의 책임이 화면 단위로 나뉘어 있으면 파일명 자체만으로도 어느 정도의 문맥을 제공해 준다는 점은 분명했습니다.

이 경험을 통해 파일 구조는 현재 코드를 읽기 위한 도구일 뿐 아니라, 과거 변경 이력을 이해하기 위한 단서가 될 수도 있다는 것을 느꼈습니다.

🍀 그렇다면 코드는 무조건 나눠야 할까?

그렇다고 무조건 나눠야 하는 것은 아니었습니다.

입력값 관리나 검증, 공통 UI처럼 정말 같은 책임을 가진 코드는 하나로 관리하는 편이 훨씬 효율적이었습니다.

결국 중요한 것은 합칠 것인가,나눌 것인가. 가 아니라 무엇이 정말 공통이고, 무엇이 화면별 책임인지 구분하는 것이었습니다.

공통화의 기준을 단순히 “현재 코드가 비슷한가?”​에만 두면 안 된다는 것을 이번 경험을 통해 느끼게 되었습니다.


🌱 마무리 - 오늘의 배움

중복을 없애는 것보다, 같은 책임을 구분하는 일이 먼저다.

예전에는 같은 코드가 두 번 보이면 먼저 합칠 방법부터 찾았습니다.

하지만 지금은 그 전에 이런 질문을 먼저 해보려고 합니다.

  • 지금만 비슷한 것일까?
  • 앞으로도 같은 방향으로 변경될 가능성이 높은가?
  • 정말 같은 책임을 가진 코드일까?

솔직히 말하자면 아직까지도 정답은 잘 모르겠습니다🤣

하지만 한 가지 분명해진 것은 중복을 제거하는 것이 목적이 아니라 변경하기 쉽고, 이해하기 쉬운 구조를 만드는 것​이 목적이라는 점입니다.

이번 경험을 통해 “같아 보이는 코드인가?”보다, “같은 이유로 함께 변경되는 코드인가?”를 먼저 생각하는 습관을 가져보려고 합니다.


.

공통화는 단순히 코드가 닮았다는 이유만으로 결정하는 것이 아니라, 책임과 변경 방향까지 함께 고려한 뒤 선택해야 하는 설계라는 것을 이번 경험을 통해 배웠습니다.

혹시 비슷한 경험을 하셨거나, 다른 의견이 있으시다면 댓글로 함께 이야기 나눠주세요😊

.

오류 및 오타, 피드백, 질문, 인사 모두 언제나 환영입니다!

읽어주셔서 감사합니다.

끝!🦕


© 2022. Haeeul All rights reserved.

🐾해을의 개발자국🐾

Powered by Hydejack v9.1.5