좋은 리팩토링 vs. 나쁜 리팩토링
(builder.io)- 코드 리팩토링은 코드베이스를 건강하게 유지하는 데 중요한 역할을 함
- 그러나 잘못된 리팩토링은 오히려 코드를 더 복잡하고 유지보수하기 어렵게 만들 수 있음
- 좋은 리팩토링과 나쁜 리팩토링을 구분하고, 나쁜 리팩토링의 함정을 피하는 방법을 알아야 함
리팩토링의 좋은 점, 나쁜 점, 그리고 추악한 점
- 추상화는 좋을 수도 있고 나쁠 수도 있음. 핵심은 언제 어떻게 적용해야 하는지를 아는 것
- 몇 가지 일반적인 함정과 이를 피하는 방법을 설명 (원문 코드는 생략)
1. 코딩 스타일을 상당히 변경하는 것
- 개발자들이 리팩토링 중에 코딩 스타일을 완전히 바꾸는 실수를 자주 함
- 새로운 라이브러리를 도입하거나 완전히 다른 코딩 스타일을 채택하는 것은 유지보수에 악영향을 줄 수 있음
- 더 관용적이고 읽기 쉬운 코드로 개선하되, 완전히 새로운 패러다임이나 외부 종속성을 도입하지 않는 것이 좋음
2. 불필요한 추상화
- 기존 코드를 이해하지 않은 채 새로운 추상화를 과도하게 추가하는 것은 문제
- 복잡성만 증가시키고 이해하기 어려워질 수 있음
- 로직을 작고 재사용 가능한 함수로 분리하되, 불필요한 복잡성은 도입하지 않는 것이 좋음
3. 불일치(Inconsistency) 추가
- 코드베이스의 한 부분만 완전히 다르게 작동하도록 업데이트하는 것은 혼란과 좌절을 야기할 수 있음
- 새로운 패턴을 도입해야 한다면, 먼저 팀의 동의를 구하는 것이 좋음
- 전체 애플리케이션에서 데이터 가져오기에 대해 일관된 접근 방식을 유지하는 것이 중요
4. 리팩토링 전에 코드를 이해하지 않음
- 코드를 배우면서 동시에 리팩토링하는 것은 좋지 않은 생각
- 버그를 만들고, 성능을 저하시키며, 기능을 제거할 수 있음
- 리팩토링하기 전에 코드를 깊이 이해하고, 기존 동작을 유지하면서 개선하는 것이 중요
5. 비즈니스 맥락 이해하기
- 비즈니스에 대한 이해 없이 기술 선택을 하는 것은 재앙이 될 수 있음
- SEO에 크게 의존하는 전자상거래 사이트의 경우, 클라이언트 측 렌더링은 나쁜 선택이 될 수 있음
- Next.js 또는 Remix와 같은 서버 사이드 렌더링 접근 방식이 SEO와 성능 측면에서 더 나은 선택이 될 수 있음
6. 지나친 코드 통합
- 유연성을 희생하면서까지 코드를 "깔끔하게" 만들기 위해 통합하는 것은 좋지 않음
- 추상화할 때는 항상 제공하는 사용 사례를 고려해야 함
- 원래의 구현이 제공했던 모든 기능을 추상화가 허용하도록 해야 함
올바른 방법으로 리팩토링하기
- 코드 리팩터링은 필요함. 하지만 올바른 방법으로 해야 함
- 우리 코드는 완벽하지 않고 정리가 필요하지만, 기존 코드베이스와 일관성을 유지해야 함
- 코드를 잘 이해한 후에 리팩터링 해야하고, 추상화는 신중하게 선택해야 함
- 성공적인 리팩터링을 위한 팁:
- 점진적으로 진행: 전면적인 재작성보다는 작고 관리 가능한 변경을 수행
- 중요한 리팩터링이나 새로운 추상화를 도입하기 전에 코드를 깊이 이해하기
- 기존 코드 스타일과 일치: 유지 보수를 위해 일관성이 핵심
- 너무 많은 새로운 추상화 도입 자제: 복잡성이 정말로 필요한 경우가 아니라면 단순하게 유지
- 특히 팀의 동의 없이 매우 다른 프로그래밍 스타일의 새로운 라이브러리 추가 자제
- 리팩터링 전에 테스트를 작성하고 진행하면서 테스트 업데이트. 이를 통해 원래의 기능을 유지하고 있는지 확인
- 동료들이 이러한 원칙을 준수하도록 서로 책임감을 가짐
더 나은 리팩터링을 위한 도구와 기술
- 더 나은 리팩터링을 위해 다음과 같은 기술과 도구 활용 고려:
린팅 도구
- 일관된 코드 스타일 적용 및 잠재적 문제 발견을 위해 린팅 도구 사용
- Prettier로 일관된 스타일로 자동 포맷팅 가능
- Eslint로 사용자 정의 플러그인을 통해 보다 세밀한 일관성 검사 수행 가능
코드 리뷰
- 리팩터링된 코드를 병합하기 전에 동료들로부터 피드백을 받기 위해 철저한 코드 리뷰 구현
- 잠재적 문제를 조기에 발견하고 리팩터링된 코드가 팀 표준 및 기대치에 부합하는지 확인하는 데 도움
테스팅
- 리팩터링된 코드가 기존 기능을 손상시키지 않도록 테스트 작성 및 실행
- Vitest는 특히 빠르고 견고하며 사용하기 쉬운 테스트 러너로 기본적으로 구성이 필요 없음
- 시각적 테스트를 위해 Storybook 사용 고려
- React Testing Library는 React 컴포넌트 테스트를 위한 좋은 유틸리티 세트 (Angular 등의 변형도 있음)
(적절한) AI 도구
- 기존 코딩 스타일과 규칙에 맞출 수 있는 AI 도구를 통해 리팩터링 노력 지원
- Visual Copilot은 프론트엔드 코딩 시 일관성을 유지하는 데 특히 유용한 도구
- 기존 코딩 스타일과 일치하고 디자인 시스템 컴포넌트와 토큰을 올바르게 활용하면서 디자인을 코드로 변환하는 데 도움을 줌
결론
- 리팩터링은 소프트웨어 개발에 필요한 부분이지만 기존 코드베이스와 팀 역학에 대한 배려와 함께 신중하게 수행되어야 함
- 리팩터링의 목표는 코드의 외부 동작을 변경하지 않고 내부 구조를 개선하는 것
- 최고의 리팩터링은 종종 최종 사용자에게 보이지 않지만 개발자의 삶을 크게 편하게 만듦
- 가독성, 유지 보수성 및 효율성은 향상시키지만 전체 시스템을 혼란스럽게 하지는 않음
- 코드에 대해 "큰 계획"을 세우고 싶을 때는 한 걸음 물러서서 코드를 철저히 이해하고, 변경의 영향을 고려하며, 팀이 감사할 수 있는 점진적인 개선을 해야 함
- 미래의 자신과 동료는 코드베이스를 깨끗하고 유지 보수 가능하게 유지하기 위한 사려 깊은 접근 방식에 감사하게 될 것
너무 당연한 말이고 기본 소양 같은 말이네요 ㅎㅎ 정리해준 것이 보기 좋네요 리팩토링 하면 100% 좋은 코드가 나온다고 봅니다 만약 아니라면 어제 보다 내 실력이 역행 했다는 것 아닐까요 ?
당연한걸 정리한 것을 보니 누가 개판 쳐놔서 진짜 빡쳐서 쓴 글 같아요 ㅎㅎㅎ
리액트에서 지나친 추상화의 신호로 한가지 사례를 경험했었는데요, 이미 UI프레임워크에 의해서 테이블 컴포넌트가 추상화되어 있는데도 두 테이블의 스키마가 유사해 보인다고 제어 역전을 써서 아무 역할도 없는 컴포넌트를 새로 만드는 건 지양해야 한다고 생각합니다. 아토믹 디자인 적용하겠다고 열 줄짜리 깡통 컴포넌트 남발하는 사례를 보니까 여러 부분을 봐야돼서 너무 불편하더라구요
DRY 규칙은 정확히 같은 모양의 같은 역할을 하는 코드를 복붙하지 말라는 의도였는데 그걸 잘못 이해하는 사람은 꼭 나오게 마련인 것 같습니다. 디자인 패턴을 맹신하지 말라는 얘기가 이런 맥락에서 나온 걸까요
테스트 코드 없이 리팩토링부터 덜컥하시는 분들도 종종 있습니다.
보고 있다 보면 위험천만한 줄타기를 하고 계시는 것 같아서 짜릿하더라구요 ㅎㅎ
리팩토링 잘하는 법이라기 보단, 현업에서 실질적으로 코딩 잘하는법..
(주니어가 와서 레거시 프로젝트 리팩토링한다고 여기저기 복잡하게 만들고 버그 만들어서 빡쳐서 쓴글같네요...)