1장 깨끗한 코드
1. 📌 핵심 개념 정리
✅ 요약하기
프로그래밍은 기계가 실행할 정도로 상세하게 요구사항을 명시하는 작업이며, 코드 없이는 요구사항을 충분히 표현하기 어렵다.
따라서 우리는 좋은 코드와 나쁜 코드를 구분하고, 나쁜 코드를 좋은 코드로 바꾸는 실력을 길러야 한다.
-
나쁜 코드
- 대충 짠 코드의 문제점
- 일정에 쫒겨서, “나중에 리팩토링하자”는 핑계로 대충 작성한 코드는 처음엔 생산성이 높아 보이지만, 시간이 지날수록 수정 시 엉뚱한 부작용을 일으키며 생산성이 0에 수렴한다.
- 개발자가 기한을 맞추기 위해 나쁜 코드를 양산하면, 그 책임은 전적으로 프로그래머에게 돌아오며, 고객이나 관리자의 요구를 무조건 따르는 행동은 전문가답지 못하다.
- 팀과 시스템에 미치는 영향
- 나쁜 코드가 쌓이면 팀 전체의 생산성이 급격히 저하된다.
- 새 인력이 추가되어도 시스템 설계에 대한 이해 부족으로 인해 오히려 나쁜 코드를 더 생산하게 된다.
- 코드의 불멸성
- "앞으로 코드가 사라질 가망은 없다"는 점에서, 한 번 작성된 코드는 시간이 지나도 계속 영향을 미치므로 처음부터 올바른 설계가 필수적이다.
- 대충 짠 코드의 문제점
-
깨끗한 코드 (좋은 코드)
- 기본 특성
- 간단하고 읽기 쉬운 코드: 코드는 단순하며, 다른 사람이 읽고 고치기 쉬워야 한다.
- 중복 제거와 명확한 역할 분담: 각 함수, 클래스, 모듈은 한 가지 역할만 수행해야 하며, 표현력 있는 이름을 사용해 중복을 줄인다.
- 초반부터 간단한 추상화 고려: 인터페이스나 추상 클래스를 먼저 정의하여, 나중에 세부 구현이 변경되어도 외부 코드에 영향을 최소화한다.
- 주의 깊게 작성: 자신이 저자이자 독자라고 생각하며, 오류 처리 등 세세한 부분까지 꼼꼼하게 신경쓴다.
- 유명 프로그래머들의 견해
- 비야네 스트롭스트룹: 깨끗한 코드는 세세한 부분까지 꼼꼼하게 처리하며 한 가지에 집중해야 한다.
- 그래디 부치: 코드에는 반드시 필요한 내용만 담아, 읽는 이에게 코드의 의도를 명확하게 전달해야 한다.
- 데이브 토마스: 읽기 쉽고 고치기 쉬운 코드가 바로 깨끗한 코드이다.
- 마이클 페더스: 깨끗한 코드는 누군가 주의 깊게 짰다는 인상을 주어야 한다.
- 론 제프리스: 중복을 피하고 한 기능만 수행하며 작게 추상화하여 의도를 명확히 해야 한다.
- 워드 커닝햄: 코드를 읽으면서 짐작했던 기능을 그대로 수행한다면 그 코드는 깨끗하다고 볼 수 있다.
- 좋은 코드 작성 실천 방안
- 보이스카우트 규칙:
"캠프장은 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라."
코드를 수정할 때마다 작게라도 개선하며, 변수 이름 개선, 긴 함수 분할, 중복 제거, 복잡한 조건문 정리 등으로 지속적으로 깨끗함을 유지한다. - 자신이 저자라 생각하고 작성: 독자들을 고려하여 우아하고 효율적인 코드를 작성한다.
- 인터페이스 기반 개발 & 프로토타이핑 후 점진적 개선
- 코드의 유연성 유지: 특정 기능이 완벽히 구현되지 않아도, 인터페이스나 추상 클래스를 통해 외부 코드가 사용할 수 있도록 한다.
- 일관된 설계 방향 유지: 추상화된 메서드를 먼저 정의하면 팀원들이 기능의 목표와 사용 방식을 쉽게 이해할 수 있다.
- TDD와의 연계: 인터페이스/추상 클래스를 먼저 작성하고 목(Mock) 객체를 활용해 테스트 가능한 구조를 만든다.
- 보이스카우트 규칙:
- 기본 특성
2. 🤔 이해가 어려운 부분
🔍 질문하기
-
한가지를 잘 아는 코드
- 어려웠던 부분
- 함수, 클래스, 모듈이 주변 상황에 현혹되지 않고 한 가지 역할에 집중하는 코드의 의미.
- 궁금한 점
- 의존성을 최대한 줄여 한 기능만 수행하게 한다면, 클래스와 메서드가 무수히 많아지지 않을까? 그 중간 선은 무엇인가?
- 어려웠던 부분
-
명쾌한 추상화
- 어려웠던 부분
- 모순적인 단어들을 합쳐서 깨끗한 코드의 특징을 나타낸 점과, 코드가 추측이 아닌 사실에 기반해야 한다는 의미.
- 궁금한 점
- 명쾌한 추상화가 구체적으로 어떻게 구현되는지 예시가 필요하다.
- 어려웠던 부분
-
작게 추상화하라!
- 어려웠던 부분
- 함수를 더 작은 단위로 분리하고, 각 요소가 명확한 역할을 가지도록 설계하는 방법.
- 이해한 점
- 짧고 명확한 함수는 읽기 쉽고 유지보수하기 좋으며, 재사용 가능성과 변경에 유연한 코드를 만든다.
- 어려웠던 부분
-
프리퀄과 원칙 (SOLID 원칙 관련)
- 어려웠던 부분
- SRP, OCP, DIP 등 다양한 설계 원칙에 대한 이해 부족.
- 궁금한 점
- “ppp의 프리퀄”이란 정확히 무엇을 의미하는가?
- 어려웠던 부분
-
마이클 페더스가 말한 깨끗한 코드
- 어려웠던 부분
- "누군가 주의 깊게 짰다는 인상"이 구체적으로 어떤 코드를 의미하는지 파악하기 어렵다.
- 궁금한 점
- 주의 깊게 짰다는 인상을 주는 코드의 구체적인 특징은 무엇인가?
- 어려웠던 부분
-
보이스카우트 규칙의 실제 적용
- 궁금한 점
- 코드를 수정할 때마다 작게라도 개선하라는 보이스카우트 규칙은, 사람마다 깨끗한 코드 기준이 달라 현실적으로 적용하기 어려운데, 이를 보완할 수 있는 대안은 무엇인가?
- 궁금한 점
-
론 제프리스의 클린 코드와 초반 간단한 추상화
- 어려웠던 부분
- 초반부터 간단한 추상화를 고려하는 방식이 과도한 추상화로 이어져 코드가 불필요하게 많아지지 않을까 하는 우려.
- 궁금한 점
- 해당 방식의 구체적인 장점과 실제 적용 사례는 무엇인가?
- 어려웠던 부분
3. 📚 참고 사항
📢 논의하기
-
관련 자료 공유
-
SOLID 원칙
- SRP (단일 책임 원칙): 각 클래스가 하나의 역할만 담당하여 유지보수가 용이해진다.
- OCP (개방-폐쇄 원칙): 확장에는 열려 있고, 수정에는 닫혀 있어야 한다.
- LSP (리스코프 치환 원칙): 자식 클래스는 부모 클래스로 대체할 수 있어야 한다.
- DIP (의존 역전 원칙): 상위 모듈은 하위 모듈에 의존하면 안 되며, 인터페이스나 추상 클래스에 의존해야 한다.
- ISP (인터페이스 분리 원칙): 클래스가 자신이 사용하지 않는 메서드에 의존하지 않도록, 인터페이스를 세분화하여 특정 클라이언트가 불필요한 기능을 강제로 구현하지 않게 해야 한다.
No Comments