BangDori 님의 상세페이지[7팀 강병준] Chapter 2-1. 클린코드와 리팩토링

과제 체크포인트

과제 링크

기본과제

  • 코드가 Prettier를 통해 일관된 포맷팅이 적용되어 있는가?
  • 적절한 줄바꿈과 주석을 사용하여 코드의 논리적 단위를 명확히 구분했는가?
  • 변수명과 함수명이 그 역할을 명확히 나타내며, 일관된 네이밍 규칙을 따르는가?
  • 매직 넘버와 문자열을 의미 있는 상수로 추출했는가?
  • 중복 코드를 제거하고 재사용 가능한 형태로 리팩토링했는가?
  • 함수가 단일 책임 원칙을 따르며, 한 가지 작업만 수행하는가?
  • 조건문과 반복문이 간결하고 명확한가? 복잡한 조건을 함수로 추출했는가?
  • 코드의 배치가 의존성과 실행 흐름에 따라 논리적으로 구성되어 있는가?
  • 연관된 코드를 의미 있는 함수나 모듈로 그룹화했는가?
  • ES6+ 문법을 활용하여 코드를 더 간결하고 명확하게 작성했는가?
  • 전역 상태와 부수 효과(side effects)를 최소화했는가?
  • 에러 처리와 예외 상황을 명확히 고려하고 처리했는가?
  • 코드 자체가 자기 문서화되어 있어, 주석 없이도 의도를 파악할 수 있는가?
  • 비즈니스 로직과 UI 로직이 적절히 분리되어 있는가?
  • 코드의 각 부분이 테스트 가능하도록 구조화되어 있는가?
  • 성능 개선을 위해 불필요한 연산이나 렌더링을 제거했는가?
  • 새로운 기능 추가나 변경이 기존 코드에 미치는 영향을 최소화했는가?
  • 코드 리뷰를 통해 다른 개발자들의 피드백을 반영하고 개선했는가?
  • (핵심!) 리팩토링 시 기존 기능을 그대로 유지하면서 점진적으로 개선했는가?

심화과제

  • 변경한 구조와 코드가 기존의 코드보다 가독성이 높고 이해하기 쉬운가?
  • 변경한 구조와 코드가 기존의 코드보다 기능을 수정하거나 확장하기에 용이한가?
  • 변경한 구조와 코드가 기존의 코드보다 테스트를 하기에 더 용이한가?
  • 변경한 구조와 코드가 기존의 모든 기능은 그대로 유지했는가?
  • (핵심!) 변경한 구조와 코드를 새로운 한번에 새로만들지 않고 점진적으로 개선했는가?

과제 셀프회고

과제를 하면서 내가 제일 신경 쓴 부분은 무엇인가요?

"제일"은 1개를 말해야겠지만, 2개를 말하겠습니닷ㅅㅇ

1. 팀원들과 코드 컨벤션 정하기!

코드 컨벤션을 정할 때 의견은 대다수가 이기는 걸로 컨벤션을 정했다.

  • singleQuote 찬성 의견: 쉬프트 키까지 쓰는 게 손가락이 아프다, 쌍따옴표는 다른 데에서 사용하기 위함이다 반대 의견: 처음부터 쌍따옴표로 개발을 시작해서 그런지 너무 익숙해졌다. (심지어 나(오하늘)만 반대함) → 결국 singleQuote은 true로 결정났다.

  • tabWidth 찬성 의견: 2가 근본이다. 반대 의견: (수줍어서 말을 하지 않으셨다.) 정말 딱 한 분 제외하고 모든 사람이 2였지만 7팀 용훈 님이 수줍게 4를 외쳤다. 따가운 시선들이 한 곳으로 모였다. → tabWidth는 2로 결정났다.

  • 세미콜론 사용 여부 찬성 의견: 코드 블럭과 코드 블럭 사이 경계가 잘 보인다, 근본이다. 반대 의견: 없는 게 더 깔끔하다. 세미콜론 사용 여부도 딱 한 분만 세미콜론을 사용하지 않으셨다. → 세미콜론은 사용하는 것으로 결론이 났다.

  • var, 동등연산자(==) 찬성 의견이 없었다. 찬성한다면 젭 나가라고 호통 쳤다.

  • 축약어 찬성 의견: 변수, 함수명이 길면 읽느라 업무 시간 다 끝난다. 모두가 알 수 있는 건 줄여 쓰는 것도 나쁘지 않다. 반대 의견: 알아듣지 못한다. 길게 쓰는 게 간지(?)다.

  • early return 찬성 의견: 그게 깔끔하다. 간지(?)다. 반대 의견: 반대 의견이 없었음.

위 코드 컨벤션을 정하고 하늘님이 very 멋지게 prettier와 eslint를 만들어서 공유해주셨다. 멋있는 사람.

그리고 나도 eslint 복붙하고 사용 중 하나가 deprecated되었다는 사실을 발견하고 빠르게 팀에 공유하여, 설정을 빠르게 수정할 수 있었고 팀원들의 개발 흐름에도 도움을 줄 수 있었다!

image

2. AI의 도움을 받되, 나만의 리팩토링 방향성을 잡기

저는 아직 경험이 많지 않기 때문에, 클린한 코드와 그렇지 않은 코드를 직접 비교해보면서 클린 코드가 주는 즐거움을 느껴보고 싶었습니다. 그래서 반복적이고 명확한 작업은 AI(Cursor)에게 맡기고, 전반적인 구조나 흐름은 스스로 판단하며 리팩토링을 진행해보려고 했습니다.

처음에는 변경 사항이 비교적 적은 부분부터 정리해 나갔습니다.

1. `var` 변수 정리 → Cursor
2. 전역 변수 및 함수들을 main 함수 내부로 이동
3. 전역 변수 네이밍 일관화
4. 사용하지 않는 코드 제거 및 중복 로직 통합
5. 템플릿 리터럴 적용
6. 매직 넘버 상수화
7. es6+ 문법 적용하기
8. UI 구조를 트리처럼 그려보고, Bottom-up 방식으로 분리 시도

ui부터는 변경 사항도 많고 고려해야 할 점도 많았습니다. Top-down으로 나누려다 변경 범위가 너무 커질 것 같아서, 최대한 기존 흐름을 깨지 않는 방향으로 Bottom-up 분리를 시도하고자 했습니다. 그래서 이런식으로 우선 트리 구조를 그렸습니다.

ui 구조 구조를 그리고 난 후, 전체적인 구조가 눈에 확 들어와서 ui를 분리하는 과정은 정말 순탄했 지 만 ..! 이후부터 굉장히 막막해지기 시작했습니다... 아 이벤트 핸들러는 어떻게 분리하지?, 아 업데이트는 어떻게 처리하지? 비즈니스 로직은? 상태는? 으아아아...

이때부터는 과제 제출 기한까지 얼마 남지 않은 상태라서 계속 고민하다가는 진도를 못나갈 것 같아 Cursor를 매우매우 적극적으로 활용하면서 진행해나갔습니다.. 지금 돌이켜보면 MVC 패턴으로 적용해서 이를 해결해보려고 했으면 어땠을까? 하는 생각이 있지만 MVC 패턴에 대한 학습 부재가 아니었나 하는 생각이 듭니다.. 흑

product.quantity; // 제품 수량

// 아이디에 해당하는 제품 찾기
function findProductById(productId) {
  return productList.find((product) => product.id === productId);
}

그래도 이 과정에서 변수명이나 함수명(.q....의 중요성과 잘 만든 함수(findProductById) 하나가 굉장히 효자라는 사실을 몸소 느끼게 되었습니다. 또 스스로 부족한 부분이 뭔지를 명확하게 느낄 수 있어서 뜻깊은 시간이었슴니다. 핫

과제를 다시 해보면 더 잘 할 수 있었겠다 아쉬운 점이 있다면 무엇인가요?

1. 요구사항을 먼저 분석하지 못했다는 점

요구사항을 읽고, 이에 대한 플로우나 정리를 간략하게라도 했더라면 애플리케이션의 전체 동작 과정을 머릿속에 그리고 더 명확하게 과제를 이해할 수 있었을 것 이라고 생각하는데 리팩토링에만 너무 성급하게 몰두했던 점이 아쉽습니다.

2. 리팩토링 방향성에 대한 의견을 나누지 못한 점

클린하게 리팩토링 해나가는 과정에서, "어떻게 다음 스텝으로 넘어가야할까?", "이건 어떻게 해야 더 가독성이 좋을까?"를 Cursor와만 소통하면서 리팩토링을 진행한 게 아쉽습니다. 팀원들과 설계나 흐름을 함께 이야기했다면 더 나은 구조가 나올 수 있었을 것이라고 생각하는데, 주도적으로 먼저 말을 꺼내지 못한 것 같습니다.

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)

  1. 리팩토링이나 기능 개발을 하다 보면 전체 흐름은 잡혔는데 세부 구조에서 계속 맴도는 경우가 종종 있습니다. 너무 깊게 고민하다가 진행이 막히는 이런 상황에서는 어떻게 풀어가야 할까요? (개인 프로젝트나 과제처럼 개인이 수행해야 하는 경우가 궁금합니다!)
  2. 추가로 기능 구현 및 리팩토링을 위한 설계는 어느정도 수준까지 이루어지는게 적절할까요? (너무 추상적인 질문이긴하지만... 전체적인 틀을 잡아주는 방향으로 대답해주시면 감사하겠습니다!!!)

과제 피드백

안녕하세요 병준님!

4주차 과제 잘 진행해주셨네요 ㅎㅎ 고생하셨습니다!!

리팩토링이나 기능 개발을 하다 보면 전체 흐름은 잡혔는데 세부 구조에서 계속 맴도는 경우가 종종 있습니다. 너무 깊게 고민하다가 진행이 막히는 이런 상황에서는 어떻게 풀어가야 할까요? (개인 프로젝트나 과제처럼 개인이 수행해야 하는 경우가 궁금합니다!)

이럴 땐 일단 한 파일에 다 몰아넣어버리는 것도 나쁘지 않은 방법이라고 생각해요 ㅎㅎ 다 만들어놓고 그 다음에 세세하게 고민하고 분리하는거죠.

어쨌든 일단 돌아가도록 만들어놓는게 제일 중요하지 않을까 싶어요!

그리고, 이 때 개선에 대한 가치 판단은 "어떻게 해야 다양한 요구사항을 수용할 수 있을까?" 에 대해 고민해보는거죠!

추가로 기능 구현 및 리팩토링을 위한 설계는 어느정도 수준까지 이루어지는게 적절할까요? (너무 추상적인 질문이긴하지만... 전체적인 틀을 잡아주는 방향으로 대답해주시면 감사하겠습니다!!!)

회사 프로젝트와 개인 학습을 위한 프로젝트가 다르다고 생각해요. 개인학습을 할 때에는 "오버엔지니어링"을 해보는게 좋습니다. 최대한 깊이있게 고민해보는거죠. 그러다보면 "이런 고민은 지금 단계에서 불필요한데!?" 라고 판단할 수 있어요. 이걸 또 실무에서 적용해보는거죠 ㅋㅋ

기능 구현 및 리팩토링을 위한 설계도... "어떤 요구사항까지 수용해야 좋을까?" 를 토대로 고민해보시면 좋답니다!

가령, 할인율에 대한 규칙이 100개정도로 늘어났을 때 이걸 최대한 자연스럽게 수용하는 구조를 상상해보시면 좋아요!

100개가 아니라 무한대의 경우의 수가 있다면 또 어떨까요? 백오피스에서 계속 할인율 규칙을 만들고 이게 어플리케이션이랑 실시간으로 동기화가 되어야 하는거죠.

이럴 때 내 코드가 수용할 수 있는 구조인가!? 라는 질문을 던져보면 좋답니다.