코드프레소 URL: https://www.codepresso.kr/
먼저 강의 목차는 아래 그림과 같이 구성되어 있습니다.
클린코드란 이해하기 쉽고, 변경하기 쉬운 Code이다. 사람이 읽고 이해하기 쉽고, 명확한 한가지 역할을 하며, 이 역할을 의미 있게 표현하고, 중복이 없고 테스트 케이스가 존재하는 코드를 말한다.
SW는 한번 신규 개발이 되고, 오랜 기간동안 유지보수가 된다. 기존 코드에 추가 작업하는 시간이 압도적으로 많으며, 대부분의 시간을 기존 코드를 읽고, 이해하는 데 사용하기 때문에 Clean Code가 중요하다. Code의 품질이 낮아지면 Code를 읽고 이해하는 데 더 많은 시간이 걸린다. 복잡도가 상승하여 코드를 수정하는 데 더 많은 시간이 걸리고, 테스트 코드가 없어서, 하나를 수정하면 여러 곳에서 Side-effect가 발생하여 결과적으로 개인과 조직 모두에게 커다란 비효율을 발생시킬 수 있다. 코드를 Clean하게 작성하면 퇴근 시간을 빠르게 만들어주고 집에 가서도 회사 전화를 받지 않게 해준다. 하지만 Clean Code를 위한 공식과 정답은 없다.
우리는 개발의 약 75%의 시간을 코드를 읽고 이해하는데 사용한다. 변수, 상수, 함수, 클래스, 파일 등 SW의 주요 요소는 이름을 갖고 있다. 좋은 이름은 내부를 들여다보지 않아도 동작과 목적을 쉽게 이해할 수 있다. 좋은 이름을 사용하면 코드를 읽는 사람의 인지적 부하를 최소화 할 수 있다.
Quora의 Ubuntu Forum의 설문 결과 프로그래머의 가장 어려운 Task로 Naming이 49%로 압도적인 결과를 나타냈다.
개발의 대부분은 코드를 이해하고 수정하는 행위이다. 수십, 수백만 라인의 코드를 읽고 이해하고 수정하는 것은 매우 어려운 일이다. Clean Naming에 대한 작은 투자는 장기적으로는 팀의 개발 생산성 향상에 크게 기여한다.
Clean Naming 대원칙
모든 이름은 반드시 그 의미가 명확해야 한다 (모두에게)
Function, Class 역할이 명확하면 Naming도 명확해 진다. 불필요한 정보와 반복은 제거해야 하며 줄임말(약어)를 사용하면 안된다. 규칙과 일관성이 중요하며 동료와의 상의가 필요하다.
Clean Function, Class의 제 1원칙
명확히 한 가지 역할을 하자
역할이 많으면 이름도 명확하지 않게 된다.
ex) createAndSaveUserInfo(), User, GeneralUtil
명확한 이름을 짓기 어려울 때는 너무 많은 역할을 하고 있는게 아닌지 고민을 해봐야 한다.
Clean Function, Class의 제 2원칙
불필요한 정보/반복은 제거하자
이름은 이해가능한 최소한의 정보를 담고 있어야 한다.
Clean Function, Class의 제 3원칙
줄임말(약어)를 사용하지 말자
줄임말은 가독성을 심각하게 저하 시킨다. 누구나 이해할 수 있는 줄임말은 존재하지 않는다. 나에게 당연한 줄임말이 타인에게는 당연하지 않을 수 있다는 것을 인지해야한다.
Clean Function, Class의 제 4원칙
규칙과 일관성은 중요하다.
언어 별, 조직 별 Naming Convention을 일관성 있게 지켜야 한다. 일관성은 코드를 이해하고 수정하는 노력을 감소 시킨다. 일관성 없는 Naming은 가독성을 저하 시킨다. 그러므로 공식 Guide를 조직에 맞게 커스터마이징 하여 내부 Guide를 결정해야 한다. 결정 된 Guide를 잘 지키고, 이견이 있을 시 공론화가 필요하다. 코드 리뷰 시 Naming등이 Guide를 잘 지키고 있는지 반드시 확인해야 한다.
Method의 이름은 의도와 기능을 명확하게 표현해야 한다. 만약 Method의 의도와 기능을 이해하기 위해 내부 코드를 들여봐야 한다면 그 Method의 이름은 개선 해야 될 필요가 있다. Method의 이름은 어떤 동작(동사)을 무엇을 대상(명사)으로 할 것인지로 표현 한다.
좋은 Method는 작고, 한 가지 일만 수행한다. 작고, 한 가지 일만 수행하는 Clean Method는 Clean Name을 짓기가 쉽다. Method 이름을 정하기 어렵다면, Method가 Clean한지를 먼저 고민해봐야 된다.
클래스의 의해 생성되는 객체를 의미 있게 설명해야한다. Class가 명확한 한 가지 책임을 갖고 있다면, 명확한 이름을 짓기가 좋다. 명사 또는 명사구를 사용하고, 동사는 사용하지 않는다.
Clean Class Naming Principle
구체적이고 명확한 이름을 사용하라
Convention을 준수하는 일관성 있는 이름을 사용하라
보편 언어를 활용하라구체적이고 명확한 이름
SW은 요구사항도출 -> 분석 -> 설계 -> 구현 -> 테스트의 반복적인 사이클이다. 요구사항 단계에서의 도메인 전무가의 멘탈 모델과 이를 구현하는 엔지니어의 멘탈 모델 사이의 커다란 Gap이 존재하는데 이는 유지보서성 낮은 SW가 만들어지는 원인이 된다.
이를 위해 엔지니어는 복잡한 현실의 문제(도메인)을 잘 파악한 후 설계와 코드에 반영해야 한다.
SW 엔지니어는 Code를 읽고 이해하고 수정하는 데 대부분의 시간을 사용한다. SW 유지보수를 효율적으로 하기 위해서는 높은 가독성이 필수적이다. 이해하기 쉬운 좋은 이름은 읽는 사람의 인지적 부하를 최소화 시킨다.
Method/Function은 SW에서 가장 기본이 되는 모듈이다. Method를 호출하는 사람이 사용하기 용이해야하며 유지보수하는 사람이 이해하고, 변경하기 용이해야 한다. Method를 유지보수 하는 사람이 테스트하기 용이해야 한다.
Clean Methods Principles
- 가능한 한 충분히 작아야 한다
- 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다
- 테스트 가능해야 한다
- 중복이 없어야 한다
Parameter 원칙
- Method를 호출하는 사람의 인지적 부하를 최소로 만들어 주어야 한다.
- Method를 호출할 때마다 내부 코드를 보거나 API 문서를 보지 않게끔 해야 함
- Parameter의 개수는 가능한 한 적어야 함
작고 역할이 명확한 메소드는 읽고 이해하기 용이하고 기존 코드를 수정하기 용히하다. 또한 단위 테스트하기 용이하며 재사용성이 높다.
한 가지의 명확한 일을 하는 Method는 명확한 Naming이 가능하고, 이름만으로 기능을 이해할 수 있다. 복잡도가 낮아질 가능성이 높다. Mehod의 내부 코드를 이해하고 수정하기 용이하며 다누이 테스트하기 용이하다.
하나의 Method는 동일한 추상화의 수준만 가져야 한다
Method의 이름이 책임지는 범위의 일만 해야 한다
중복 코드란 일정 라인 수 이상이 다수 중복되어 존재하는 코드이다. 개발자는 복사/붙여넣기의 유혹과 갈등하는 경우가 있는데, 이런 중복 코드는 다양한 문제점을 발생 시킨다.
불필요하게 코드 베이스를 크게 만들고 코드를 수정해야 할 때 중복 된 다수의 코드를 모두 수정해야 한다. 중복 코드에 잠재적 결함이 있을 시, 결함도 같이 중복 된다.
이러한 중복 코드를 발견하기 위해서는 첫 번째로 코드 리뷰를 하는 것이다. 하지만 수동으로 전체 SW 시스템의 중복을 다 발견하기는 쉽지 않는데 이를 위한 정적 분석이라는게 있다. 이는 중복 코드를 찾아내는 정적 분석 도구를 활용하는 것인데, 그 도구로는 CPD와 Atomiq - Code Similartity Finder가 있다.
Comment는 Code에 대한 사람이 읽을 수 있는 부가 설명이다. 사람이 Code를 더 쉽게 이해할 수 있게 하는 것이 목적이며, 일반적으로 Compiler/Interpreter는 Comment를 실행하지 않고 무시한다.
Clean Comment Principle
- Comment는 필요악이다
- Comment는 대부분의 상황에서 사용하지 말아야 한다
- 그러나 Comment를 사용해야 하는 몇 가지 예외 상황이 있다
Comment로 부가 설명이 필요하면 Code가 충분히 의미 있지 못하다는 것이다. 의미 있는 이름, 명확한 Code는 어렵고, Comment는 쉽다. Comment에 의지하기 보다 의미 있는 Code를 작성하는 노력이 필요하다.
99%의 Comment는 불필요하다.
다양한 Bad Comment의 유형이 있는데, 기억해야 할 1 가지는 Comment는 Code Bad Smell이다.
Comment를 사용하지 않는 것이 최고의 Clean Comment이다. 진실은 오직 Code에만 존재하며 Code로 의미를 표현해야 한다.
Code Formatting은 코드의 가독성과 이해도를 높여주는 일련의 작업이다. 수직적 Formatting 원칙과 수평적 Formatting 원칙으로 분류된다.
Donald Knuth에 의해 주창된 개념으로 코드는 사람이 읽도록 만들어지는 것이 우선이다. 문학 작품을 읽는 것처럼 코드를 읽을 수 있도록 만들어져야 하며 프로그래밍이란 컴퓨터가 어떤 동작을 하기 원하는지 "사람에게 설명"하는 행이다.
코드의 위에서 아래로 진행된 흐름과 관련 된 코드 작성 규칙으로 코드 라인간의 간격, 밀접한 관계를 가지는 코드 간 그룹화 등 이 포함된다.,
하나의 코드 행에서 왼쪽에서 오른쪽으로 진행된 흐름과 관련 된 코드 작성 규칙으로 들여쓰기, 코드 간 간격, 코드 행의 넓이 등이 포함된다.
수직적 Formatting은 Enter 같은 개행 문자를 이용해 Formatting 하는 것을 의미한다. 마치 신문기사처럼 위에서 아래 쉽게 읽혀 나갈 수 있는 것을 목표로 한다.
추상화의 수준 순서로 코드를 배치
서로 다른 개념은 분리
유사한 개념은 모아 놓음
수평적 Formatting은 코드 한 줄에 대해서 Formatting 하는 것을 의미한다. 좌우 횡스크롤링 없이 코드를 읽을 수 있어야 하며 코드 한 줄을 스크롤의 이동없이 볼 수 있는 것을 목표로 한다.(약 80자)
Control Structures 란?
조건, 루프(loop), 흐름을 제어하는 선언문
매직 넘버란, 그 의미를 알 수 없는 임의의 수를 말한다. 조건문에서의 매직 넘버는 코드의 가독성을 해치는 주요 원인으로 코드를 이해하기 위해 별도의 문서와 시간이 필요하다.
조건문을 구성하는 오른쪽 항의 값은 잘 설명할 수 있는 명확한 상수로 설계되어야 한다.
삼항연산자를 사용하려면 항산 가독성을 고려해야 한다. 코드의 라인을 최소화하는 것 보다, 코드를 이해하는 시간을 최소화하는 것이 중요하다.
핵심 로직을 처리 하기 전에 다수의 사전 검증 로직이 필요한 경우 사전 검증 로직과 핵심 로직이 혼재되어 코드의 가독성이 낮아질 수 있다.
이를 대비하기 위해서 검증 영역과 핵심 로직 영역을 분리시키면 Method의 복잡도가 낮아져 가독성이 향상되고, 테스트가 용이해진다.
Fail Fast란?
빨리 실패하는 '검증로직'을 다시 method로 분리하고 예외를 사용하면 코드의 가독성은 더욱 높이고, 복잡도는 낮출 수 있다.
긍정적인 표현은 부정적 표현보다 이해하기 상대적으로 용이하므로, 조건문은 긍정 표현을 사용하는 것이 가독성 관점에서 좋다.
SW 품질 향상을 목적으로 기능의 변경 없이, 내부 코드를 변경하는 기술로 2000년에 Martin Fowler가 소개하였다.
Refactoring의 철한은 티끌 모아 태산으로 기존 기능에 변경을 가하지 않는 수준의 아주 작은 코드 개선 작업니다. 하나 하나의 Refactoring은 너무 작아서 큰 의미가 없지만 작은 개선이 쌓이면 의미 있는 품질 향상이 가능하다.