-
Notifications
You must be signed in to change notification settings - Fork 0
“Code 하이라이팅” 코드 품질 개선
[ 참고 ]
기존 프로젝트 구조는 FSD이지만, 코드 하이라이팅 관련 코드들은 따로 shared에 분리하여 다른 폴더에 가져다 붙이기만 해도 동작할 수 있게 하려는 목표로 구조를 짜고 구성하였습니다.
처음에는 코드 하이라이팅 관련 코드가 복잡하고 가독성이 떨어져, 오랜 시간이 지나면 저조차도 코드의 의도를 파악하기 어려웠습니다. 이를 해결하기 위해 명확한 코드 품질 기준을 정립하고, 누구나 쉽게 이해할 수 있는 구조로 개선하여 유지보수성을 높이고자 했습니다.
품질 개선은 CS 원리와도 밀접한 연관이 있습니다. 예를 들어, 중복 코드를 제거하거나 매직 넘버를 상수로 대체하는 작업은 소프트웨어 엔지니어링 원칙(SOLID) 중 단일 책임 원칙(SRP)을 준수하는 것이며, 데이터 구조와 알고리즘의 적절한 선택은 성능 최적화와 직결됩니다.
결과적으로, 코드 품질 개선은 단순히 규칙을 따르는 것을 넘어, CS의 기본 원리를 실천하며 협업을 용이하게 하고 코드의 확장성과 안정성을 높이는 과정입니다.
여러가지 SonarCloud, Code Climate, DeepSource 등등 여러 도구가 있지만, 설정하고 연동을 해야한다.
하지만, 계속 무언가를 추가하기 싫었다.
그래서 나만의 기준을 만들고 이를 기반으로 개선 정도를 점수로 수치화하려고 한다.
해당 글을 참고해서 기준을 정하였습니다. 밑의 말이 참 와닿았습니다.
**"좋은 프론트엔드 코드는 변경하기 쉬운 코드"**
중복 및 불필요한 코드
- 3번 이상 반복되는 로직: 10점
- 불필요한 조건문: 10점
- 안 쓰이는 코드: 10점
파일 구조 및 명명
- 파일 구조 명확성: 10점
- 이름 명명의 직관성: 10점
유지보수성
- 매직 넘버/문자 제거: 10점
- 단일 책임 원칙 준수: 10점
가독성
- 맥락 줄이기 (5점)
- 구현 상세 추상화 (5점)
- 코드 스타일 일관성 (5점)
성능 및 안정성
- 비동기 처리: 10점
- 메모리 누수 방지: 5점
위에서 정한 기준으로 AI에게 내 코드에 점수를 매겨달라고 했다.
🤖 AI 코드 품질 평가
1. 중복 및 불필요한 코드
-
3번 이상 반복되는 로직 (10점):
-
selectedBlockStartLine
,selectedBlockLength
,selectedBlockType
와 관련된 로직이CodeContent.tsx
와CodeViewer.tsx
에서 반복적으로 사용되고 있음. 이를 유틸 함수로 분리할 수 있음. 점수: 6/10
-
-
불필요한 조건문 (10점):
- 조건문이 단순하지 않거나 중복으로 사용된 부분 없음. 다만,
CodeContent.tsx
에서selectedBlockType
관련 조건문이 더 간결하게 리팩토링될 수 있음. 점수: 8/10
- 조건문이 단순하지 않거나 중복으로 사용된 부분 없음. 다만,
-
안 쓰이는 코드 (10점):
- 사용되지 않는 변수나 함수는 없으며, 불필요한 import도 보이지 않습니다. 점수: 10/10
2. 파일 구조 및 명명
-
파일 구조 명확성 (10점):
- 기능별로 컴포넌트와 유틸, 스타일 파일이 명확히 나뉘어 있음.
utils
와 같은 폴더 구조가 잘 활용됨. 점수: 10/10
- 기능별로 컴포넌트와 유틸, 스타일 파일이 명확히 나뉘어 있음.
-
이름 명명의 직관성 (10점):
- 함수, 변수, 컴포넌트의 이름이 기능과 목적을 명확히 나타냄.점수: 10/10
3. 유지보수성
-
매직 넘버/문자 제거 (10점):
- CSS에서 색상 코드, 컴포넌트에서
1000ms
와 같은 값들이 하드코딩되어 있음. 이를 상수로 관리하면 유지보수성이 향상될 것. 점수: 7/10
- CSS에서 색상 코드, 컴포넌트에서
-
단일 책임 원칙 준수 (10점):
- 대부분의 컴포넌트가 단일 역할을 수행하고 있으나,
CodeViewer.tsx
에서 렌더링 로직과 비즈니스 로직(parseHighlight 관련)이 결합되어 있습니다. 분리 가능성이 있음. 점수: 8/10
- 대부분의 컴포넌트가 단일 역할을 수행하고 있으나,
4. 가독성
-
맥락 줄이기 (5점):
- 코드 내 맥락을 줄이기 위해 로직 분리가 필요한 부분이 있으며, 복잡한 조건문이나 계산식을 함수로 추출하면 가독성이 개선될 여지가 있습니다. 점수: 4/5
-
구현 상세 추상화 (5점):
- 세부 구현 로직을 별도 함수로 분리한 부분이 많지만,
CodeViewer.tsx
의parseHighlight
관련 로직을 더욱 추상화할 여지가 있습니다. 점수: 4/5
- 세부 구현 로직을 별도 함수로 분리한 부분이 많지만,
-
코드 스타일 일관성 (5점):
- Prettier와 ESLint 규칙이 적용된 것으로 보이며, 스타일 일관성이 유지됩니다. 점수: 5/5
5. 성능 및 안정성
-
비동기 처리 (10점):
- 비동기 처리 로직이 많이 포함되어 있지는 않음. 다만, 타이머(
setTimeout
)가 적절히 정리되고 있어 문제가 없음.점수: 10/10
- 비동기 처리 로직이 많이 포함되어 있지는 않음. 다만, 타이머(
-
메모리 누수 방지 (5점):
- 모든 비동기 작업 및 이벤트 리스너가 적절히 정리되고 있음. 메모리 누수 가능성 없음.점수: 5/5
최종 점수
평가 항목 | 점수 |
---|---|
중복 및 불필요한 코드 | 24/30 |
파일 구조 및 명명 | 20/20 |
유지보수성 | 15/20 |
가독성 | 13/15 |
성능 및 안정성 | 15/15 |
합계 | 87/100 |
개선 목표 점수 = 100점
100점이라고 해서 완벽하다는 것은 아니고, 최소한의 품질이 100점이라고 생각한다.
처음 코드를 짤때는 CodeViewer 컴포넌트를 상단에 두고 밑의 하위 2개의 컴포넌트(LineNumbers, CodeContent)를 불러오는 구조를 이뤘다.
하지만, CodeViewer
→ CodeContent
이렇게 Props Drilling 이 되는 문제가 있었다.
기존 CodeViewer.tsx
- 위 사진을 보면 selectedBlockLength, selectedBlockStartLine, selectedBlockType 이 3개 속성을
CodeContent
컴포넌트로 보낸다.
기존 CodeContent.tsx
- 위에서 받아온 3개 속성이 getClassNames 함수 변수로 그대로 다시 들어간다.
- Props Drilling이다. 이는 부모 컴포넌트와 자식 컴포넌트 사이에 결합도가 생겼다는 표시이다.\
- 그래서 이걸 굳이 2개의 컴포넌트로 나누지 않고 CodeContent 부분을 부모 컴포넌트로 올려서 Props Drilling을 없앴다.
Props Drilling을 지운 CodeContent.tsx
-
CodeContent
컴포넌트를 없애고CodeViewer
컴포넌트로 합쳐졌다.
- 애니메이션 지속 시간 상수화
• 기존에는 components, styles, utils로만 이루어져 있었던 것을 폴더 구조를 더 나누고 추가하였다. utils에 함수들도 더 추가되었다.
커스텀훅: useDiffCodeAnimate.ts
계산 로직: getParsedCodeLineList.ts
타입: types/index.ts
- 기존에는 "UI 렌더링 로직", "계산 로직", "데이터 처리 로직" 이 3가지가 한 파일 안에서 다 처리가 됐었다.
- 코드 양이 엄청 길지도 않았고, 구현 데드라인을 지키기 위해서 급급히 짜다보니 생긴 문제다.
- 다시 보니, 파싱하는 코드 처리이다보니 길이는 짧아도 조건문이 복잡해서 어떤 방식으로 돌아가는지 바로 이해가 되지 않았다. 그래서 조건문 계산 로직들을 다 함수로 분리하고, 데이터 처리하는 것도 커스텀 훅으로 관리하여 해당 3가지를 다 기능별로 분리하였다. 이후 선언형으로 해당 함수들을 불러오기만 하고 처리하게 하여서, 좀 더 코드의 의미가 명확해지고 가독성이 좋아졌다.
분리된 최종 구조.
- 추상화, 중복 코드 제거, 파일 구조 정리, 유지보수성 향상, 가독성 개선
- 코드 품질 점수 100점으로 향상
- 유지보수성, 가독성 향상으로 “변경하기 쉬운 코드”로 개선.
🌐 참고 링크