목차4개 항목
출처와 참고
ByteByteGo의 System Design 101 가이드 「10 Good Coding Principles to Improve Code Quality」를 바탕으로 재구성한 노트다.
좋은 코드란
좋은 코드는 읽기 쉽고, 바꾸기 쉽고, 예상 밖의 입력에도 무너지지 않는 코드다. 코드는 쓰는 시간보다 읽히고 고쳐지는 시간이 훨씬 길다. 아래 원칙은 모두 "나중에 이 코드를 고칠 사람"의 비용을 줄이는 쪽을 향한다.
열 가지 원칙
| # | 원칙 | 무엇을 하나 | 왜 |
|---|---|---|---|
| 1 | 코드 규약을 따른다 | PEP 8, Google Java Style 같은 업계 규약이나 팀 규약을 정하고 포매터·린터로 강제한다 | 모양이 같으면 내용에 집중할 수 있다. 스타일 논쟁을 리뷰에서 없앤다 |
| 2 | 주석은 "왜"를 쓴다 | 무엇을 하는지는 코드가 말하게 하고, 주석과 문서에는 그 방식을 택한 이유와 결정을 남긴다 | "무엇" 주석은 코드와 어긋나며 거짓말이 된다. 주석과 문서도 코드처럼 갱신한다 |
| 3 | 견고하게 만든다 | 예외와 경계 입력을 처리해 예상 밖 상황에서도 멈추거나 엉뚱한 결과를 내지 않게 한다 | 실제 입력은 늘 명세보다 지저분하다 |
| 4 | SOLID를 따른다 | 단일 책임, 개방·폐쇄, 리스코프 치환, 인터페이스 분리, 의존성 역전 | 변경이 한곳에 모이고 확장이 기존 코드를 덜 건드린다(SOLID 원칙) |
| 5 | 테스트하기 쉽게 만든다 | 구성 요소의 복잡도를 낮추고 의존성을 주입받게 해 자동화 테스트를 붙이기 쉽게 한다 | 테스트하기 어려운 코드는 대개 설계가 엉킨 코드다 |
| 6 | 추상화는 적당히 | 핵심 로직을 뽑아내고 복잡도를 감춘다. 지나치게 일반화하지도, 확장을 아예 막지도 않는다 | 추상화는 비용이다. 같은 코드가 세 번째 나올 때 뽑는다(추상화 계층과 데이터 흐름) |
| 7 | 패턴은 쓰되 과설계하지 않는다 | 디자인 패턴은 맞는 상황에만 쓴다 | 남용한 패턴은 코드를 더 복잡하고 읽기 어렵게 만든다(GoF 디자인 패턴) |
| 8 | 전역 의존을 줄인다 | 전역 변수·싱글톤 대신 지역 상태와 매개변수로 넘긴다. 함수는 부수 효과 없이 짠다 | 전역 상태는 누가 언제 바꿨는지 추적할 수 없게 만든다 |
| 9 | 계속 리팩터링한다 | 문제를 일찍 발견해 조금씩 고친다 | 기술 부채는 이자가 붙는다. 한꺼번에 갚으려 하면 못 갚는다(기술 부채) |
| 10 | 보안을 최우선으로 | 입력 검증, 비밀 정보 분리, 최소 권한 같은 기본을 지켜 흔한 취약점을 피한다 | 보안 결함은 다른 결함보다 비용이 훨씬 크다(API 보안 체크리스트) |
원칙끼리 부딪칠 때
원칙은 서로 당긴다. 판단 기준은 "지금 알려진 변경"에 맞추고, 상상 속 변경에는 투자하지 않는다는 것이다.
| 긴장 | 판단 |
|---|---|
| 추상화(6) ↔ 단순함 | 같은 코드가 세 번 나올 때 추상화한다. 두 번까지는 중복이 잘못된 추상화보다 싸다 |
| 견고함(3) ↔ 가독성 | 경계에서(외부 입력, API 응답) 검증하고, 내부에서는 믿는다. 모든 함수에 방어 코드를 깔지 않는다 |
| 패턴(7) ↔ SOLID(4) | SOLID를 지키려고 인터페이스를 미리 늘리면 과설계가 된다. 변경이 실제로 일어날 때 확장점을 만든다 |
| 리팩터링(9) ↔ 일정 | 기능 작업 안에서 지나가는 코드를 조금씩 정리한다. 리팩터링만 하는 큰 작업은 계획을 따로 세운다 |
정리
- 좋은 코드는 다음에 고칠 사람의 비용을 줄이는 코드다.
- 규약과 포매터로 모양을 맞추고, 주석에는 이유를 남긴다.
- SOLID, 테스트 용이성, 지역 상태는 변경을 한곳에 모으는 같은 목표의 다른 얼굴이다.
- 추상화와 패턴은 필요가 증명될 때 쓴다. 과설계도 부채다.
- 리팩터링은 습관으로, 보안은 기본값으로 둔다.
관련 노트: 클린 코드: 함수와 이름, 프론트엔드와 SOLID 원칙, GoF 디자인 패턴, 코드 리뷰 원칙과 체크리스트, 기술 부채, 변경하기 쉬운 코드의 네 가지 기준