클린 코드
장민석
책
나쁜 코드로 치르는 대가
망함
태도
• 관리자가 재촉했다구욧!
• 요구사항이 뒤집혔다구욧!
• 일정이 촉박했다구욧!
핑계
우리는 전문가. 좋은 코드를 사수하는 것은 프로그래머의 책임이다.
깨끗한 코드라는 예술
• 깨끗한 코드는 그림 그리는 작업과 같다.
• 그림을 잘 그렸는지 알 수 있다고, 그림을
잘 그릴 수 있는 건 아니다.
• 깨끗한 코드를 알아볼 수 있다고, 깨끗한 코
드를 짤 수 있는 건 아니다.
계속해서 짜보지 않으면,
절대 깨끗한 코드를 짤 수 없음
클린 코드란 어떤 코드인가
• 깨끗한 코드는 한 가지를 제대로 한다.
• 깨끗한 코드는 단순하고 직접적이다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다.
• 깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다.
• 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌은 준다.
• 중복을 피하라. 한 기능만 수행하라. 제대로 표현하라. 작게 추상화하라.
• 코드를 읽으면서 짐작했던 기능을 각 루틴이 제대로 수행한다
우리는 저자다
• @author. 우리는 저자다.
• 코드를 읽는 시간과 짜는 시간의 비율은 10대1이 넘는다!
• 저자에게는 독자와 소통할 책임이 있다.
그렇다면 어떻게 짜면 될까
이것은 절대적인 것이 아니다.
(객체지향 언어의 관점에서 쓰여졌다.)
의미 있는 이름
의도를 분명히 밝혀라
• 의도가 분명한 이름을 짓는 것은 정말로 중요하다
int d (X) Int daysSinceCreation (O)
그릇된 정보를 피하라
• 타입이 List가 아니라면 AccountList같은 명명을 하지 마라.
• 소문자 L이나 대문자 O를 변수로 쓰지 마라.
의미 있게 구분하라
• class라는 이름이 있다고 klass라고 짓는 다 거나,
• zork라는 이름을 이미 쓰고 있다고, theZork라고 짓지 마라.
• 읽는 사람이 차이를 알도록 지어라.
발음하기 쉬운 이름을 사용하라
• 발음하기 쉬운 단어로 이름을 지어라
Date genymdhms (X) Date generationTimestamp (O)
검색하기 쉬운 이름을 사용하라
• 검색하기 쉬운 단어로 이름을 지어라.
5 (X) WORK_DAYS_PER_WEEK (O)
자신의 기억력을 자랑하지 마라
• 루프의 반복 변수(I,J) 정도 외에 한 글자로 이름 짓지 마라
기발한 이름은 피하라
• kill() 대신 whack() 이라는 이름으로 짓지 마라
한 개념에 한 단어를 사용하라
• 똑같은 메서드를 클래스마다 fetch, get, retrieve라고 짓는 일은
하지 마라
말장난을 하지 마라
• ‘한 개념에 한 단어를 사용하라’를 따른다고 다른 개념에 같은
이름을 붙이지 마라
• 전부 add를 쓰고 있다고, 다른 동작을 하는 새 메서드에 add라
고 붙여선 안된다.
의미 있는 맥락을 추가하라
• firstName, state, housedNumber 등의 변수가 있다면,
• 변수에 접두어 Addr을 붙이거나,
Address 클래스를 만들어 맥락을 표현하라
불필요한 맥락을 없애라
• 우리 애플리케이션 이름이 GSD라고,
모든 클래스에 GSD 접두어를 붙이는 짓은 하지 마라
함수
작게 만들어라!
• 함수를 만드는 첫째 규칙은 ‘작게!’다. 둘째 규칙도 ‘작게!’다
• 20줄도 길다
• 들여쓰기가 1, 2단 이상 넘으면 안 된다. 넘으면 쪼개야 된다.
한 가지만 해라!
• 함수는 한 가지를 해야 한다.
• 그 한 가지를 잘해야 한다.
• 그 한 가지만을 해야 한다.
함수 당 추상화 수준은 하나로!
• 한 가지를 하기 위해서는 모든 문장의 추상화 수준이 동일해야
한다.
• getHTML()과
• String pageName = PathParser.render(pagePath)와
• append(“n”)은 추상화 수준이 다르다.
• 한 함수에 추상화 수준이 섞이면 이해가 힘들어진다.
서술적인 이름을 사용하라!
• 이름이 길어도 괜찮다. 길고 서술적인 이름이 짧고 어려운 이름
보다 좋다.
함수 인수
• 이상적인 인수의 개수는 0개 이고, 3개 이상은 피하는 게 좋다.
• 인수가 많아질수록 이해하기 어렵다.
• 테스트하기 어렵다.
• 플래그 인수는 추하다.
• render(isSuite)
부수효과를 일으키지 마라!
• 함수 내부에서 남몰래 전역 변수를 수정하거나 하는 등의 일은
하면 안 된다.
명령과 조회를 분리하라!
• 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야
한다.
오류코드 보다 예외를 사용하라!
• 오류코드를 리턴 하는 방식은 이후 if문을 만들어낸다.
• If(deletePage(page) == E_OK)
• try/catch블록은 원래 추하다. 따라서 try/catch블록만 따로 함수
로 뽑아내는 것이 좋다.
Public void delete(Page page) {
try{
deletePageAndAllReference(page);
}
catch(Exception e) {
logError(e);
}
}
반복하지 마라!
• 중복은 소프트웨어에서 만악의 근원이다.
함수를 어떻게 짜죠?
• 소프트웨어를 짜는 행위는 글짓기와 비슷하다.
• 어설픈 초안을 만들고, 테스트 케이스를 짠 뒤, 함수를 다듬는다.
주석
주석
• 우리는 의도를 코드로 표현하지 못해, 그러니까 실패를 만회하
기 위해 주석을 사용한다.
• 진실은 한 곳에만 존재한다. 바로 코드다.
• 코드는 변화하고 진화한다. 슬프게도 대부분 주석은 이를 따라
가지 못한다.
주석은 나쁜 코드를 보완하지 못한다
• 자신이 저지른 난장판을 주석으로 설명하려 애쓰는 대신, 그 난
장판을 깨끗이 치우는 데 시간을 써라
• 대다수 의도를 코드로 표현할 수 있다.
형식 맞추기
형식 맞추기
• 코드 형식은 중요하다! 프로그래머라면 형식을 깔끔하게 맞춰
코드를 짜야 한다.
적절한 행 길이를 유지하라
• 200줄 정도의 파일들로도 커다란 시스템을 구축할 수 있다.
• 일반적으로 큰 파일 보다 작은 파일이 이해하기 쉽다.
개념은 빈 행으로 분리하라
• 패키지 선언부, import문, 각 함수 사이에 빈 행이 들어간다.
• 빈 행이 없는 코드를 상상해보라
세로 밀집도
• 서로 밀접한 코드 행은 세로로 가까이 놓여야 한다.
수직 거리
• 변수 선언 : 변수는 사용하는 위치에 최대한 가까이 선언한다.
• 인스턴스 변수 : 인스턴스 변수는 클래스 맨 처음에 선언한다.
• 종속 함수 : 한 함수가 다른 함수를 호출한다면, 두 함수는 세로로 가까이 배치한다.
• 개념적 유사성 : 같은 변수를 사용하거나 하는, 동작이 비슷한 함수는 가까이 배치한다.
세로 순서
• 함수 호출의 종속성은 아래 방향으로 유지한다.
• 호출되는 함수를 호출하는 함수보다 나중에 배치한다.
가로 공백과 밀집도
• 가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한
다.
• 할당문에 공백을 주어 왼쪽/오른쪽 요소를 확실히 나눌 수 있고,
• 함수이름과 괄호는 밀접하기에 공백을 넣지 않는다.
Int lineSize = line.length() Private void measureLine(String line)
들여 쓰기
• 간단한 if문, while문, 함수에서 들여쓰기를 무시하고 싶은 충동
을 이겨내라!
Public String render() {return “”;}
Public String render() {
return “”;
}
팀 규칙
• 팀은 한 가지 규칙에 합의해야 한다. 그리고 모든 팀원이 그 규
칙을 따라야 한다.
• 한 소스파일에서 봤던 형식이 다른 소스파일에서도 쓰이리라는
생각을 갖게 해야 한다.

클린 코드 part1

  • 1.
  • 2.
  • 3.
  • 4.
    태도 • 관리자가 재촉했다구욧! •요구사항이 뒤집혔다구욧! • 일정이 촉박했다구욧! 핑계 우리는 전문가. 좋은 코드를 사수하는 것은 프로그래머의 책임이다.
  • 5.
    깨끗한 코드라는 예술 •깨끗한 코드는 그림 그리는 작업과 같다. • 그림을 잘 그렸는지 알 수 있다고, 그림을 잘 그릴 수 있는 건 아니다. • 깨끗한 코드를 알아볼 수 있다고, 깨끗한 코 드를 짤 수 있는 건 아니다. 계속해서 짜보지 않으면, 절대 깨끗한 코드를 짤 수 없음
  • 6.
    클린 코드란 어떤코드인가 • 깨끗한 코드는 한 가지를 제대로 한다. • 깨끗한 코드는 단순하고 직접적이다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다. • 깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다. • 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌은 준다. • 중복을 피하라. 한 기능만 수행하라. 제대로 표현하라. 작게 추상화하라. • 코드를 읽으면서 짐작했던 기능을 각 루틴이 제대로 수행한다
  • 7.
    우리는 저자다 • @author.우리는 저자다. • 코드를 읽는 시간과 짜는 시간의 비율은 10대1이 넘는다! • 저자에게는 독자와 소통할 책임이 있다.
  • 8.
    그렇다면 어떻게 짜면될까 이것은 절대적인 것이 아니다. (객체지향 언어의 관점에서 쓰여졌다.)
  • 9.
  • 10.
    의도를 분명히 밝혀라 •의도가 분명한 이름을 짓는 것은 정말로 중요하다 int d (X) Int daysSinceCreation (O)
  • 11.
    그릇된 정보를 피하라 •타입이 List가 아니라면 AccountList같은 명명을 하지 마라. • 소문자 L이나 대문자 O를 변수로 쓰지 마라.
  • 12.
    의미 있게 구분하라 •class라는 이름이 있다고 klass라고 짓는 다 거나, • zork라는 이름을 이미 쓰고 있다고, theZork라고 짓지 마라. • 읽는 사람이 차이를 알도록 지어라.
  • 13.
    발음하기 쉬운 이름을사용하라 • 발음하기 쉬운 단어로 이름을 지어라 Date genymdhms (X) Date generationTimestamp (O)
  • 14.
    검색하기 쉬운 이름을사용하라 • 검색하기 쉬운 단어로 이름을 지어라. 5 (X) WORK_DAYS_PER_WEEK (O)
  • 15.
    자신의 기억력을 자랑하지마라 • 루프의 반복 변수(I,J) 정도 외에 한 글자로 이름 짓지 마라
  • 16.
    기발한 이름은 피하라 •kill() 대신 whack() 이라는 이름으로 짓지 마라
  • 17.
    한 개념에 한단어를 사용하라 • 똑같은 메서드를 클래스마다 fetch, get, retrieve라고 짓는 일은 하지 마라
  • 18.
    말장난을 하지 마라 •‘한 개념에 한 단어를 사용하라’를 따른다고 다른 개념에 같은 이름을 붙이지 마라 • 전부 add를 쓰고 있다고, 다른 동작을 하는 새 메서드에 add라 고 붙여선 안된다.
  • 19.
    의미 있는 맥락을추가하라 • firstName, state, housedNumber 등의 변수가 있다면, • 변수에 접두어 Addr을 붙이거나, Address 클래스를 만들어 맥락을 표현하라
  • 20.
    불필요한 맥락을 없애라 •우리 애플리케이션 이름이 GSD라고, 모든 클래스에 GSD 접두어를 붙이는 짓은 하지 마라
  • 21.
  • 22.
    작게 만들어라! • 함수를만드는 첫째 규칙은 ‘작게!’다. 둘째 규칙도 ‘작게!’다 • 20줄도 길다 • 들여쓰기가 1, 2단 이상 넘으면 안 된다. 넘으면 쪼개야 된다.
  • 23.
    한 가지만 해라! •함수는 한 가지를 해야 한다. • 그 한 가지를 잘해야 한다. • 그 한 가지만을 해야 한다.
  • 24.
    함수 당 추상화수준은 하나로! • 한 가지를 하기 위해서는 모든 문장의 추상화 수준이 동일해야 한다. • getHTML()과 • String pageName = PathParser.render(pagePath)와 • append(“n”)은 추상화 수준이 다르다. • 한 함수에 추상화 수준이 섞이면 이해가 힘들어진다.
  • 25.
    서술적인 이름을 사용하라! •이름이 길어도 괜찮다. 길고 서술적인 이름이 짧고 어려운 이름 보다 좋다.
  • 26.
    함수 인수 • 이상적인인수의 개수는 0개 이고, 3개 이상은 피하는 게 좋다. • 인수가 많아질수록 이해하기 어렵다. • 테스트하기 어렵다. • 플래그 인수는 추하다. • render(isSuite)
  • 27.
    부수효과를 일으키지 마라! •함수 내부에서 남몰래 전역 변수를 수정하거나 하는 등의 일은 하면 안 된다.
  • 28.
    명령과 조회를 분리하라! •함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야 한다.
  • 29.
    오류코드 보다 예외를사용하라! • 오류코드를 리턴 하는 방식은 이후 if문을 만들어낸다. • If(deletePage(page) == E_OK) • try/catch블록은 원래 추하다. 따라서 try/catch블록만 따로 함수 로 뽑아내는 것이 좋다. Public void delete(Page page) { try{ deletePageAndAllReference(page); } catch(Exception e) { logError(e); } }
  • 30.
    반복하지 마라! • 중복은소프트웨어에서 만악의 근원이다.
  • 31.
    함수를 어떻게 짜죠? •소프트웨어를 짜는 행위는 글짓기와 비슷하다. • 어설픈 초안을 만들고, 테스트 케이스를 짠 뒤, 함수를 다듬는다.
  • 32.
  • 33.
    주석 • 우리는 의도를코드로 표현하지 못해, 그러니까 실패를 만회하 기 위해 주석을 사용한다. • 진실은 한 곳에만 존재한다. 바로 코드다. • 코드는 변화하고 진화한다. 슬프게도 대부분 주석은 이를 따라 가지 못한다.
  • 34.
    주석은 나쁜 코드를보완하지 못한다 • 자신이 저지른 난장판을 주석으로 설명하려 애쓰는 대신, 그 난 장판을 깨끗이 치우는 데 시간을 써라 • 대다수 의도를 코드로 표현할 수 있다.
  • 35.
  • 36.
    형식 맞추기 • 코드형식은 중요하다! 프로그래머라면 형식을 깔끔하게 맞춰 코드를 짜야 한다.
  • 37.
    적절한 행 길이를유지하라 • 200줄 정도의 파일들로도 커다란 시스템을 구축할 수 있다. • 일반적으로 큰 파일 보다 작은 파일이 이해하기 쉽다.
  • 38.
    개념은 빈 행으로분리하라 • 패키지 선언부, import문, 각 함수 사이에 빈 행이 들어간다. • 빈 행이 없는 코드를 상상해보라
  • 39.
    세로 밀집도 • 서로밀접한 코드 행은 세로로 가까이 놓여야 한다.
  • 40.
    수직 거리 • 변수선언 : 변수는 사용하는 위치에 최대한 가까이 선언한다. • 인스턴스 변수 : 인스턴스 변수는 클래스 맨 처음에 선언한다. • 종속 함수 : 한 함수가 다른 함수를 호출한다면, 두 함수는 세로로 가까이 배치한다. • 개념적 유사성 : 같은 변수를 사용하거나 하는, 동작이 비슷한 함수는 가까이 배치한다.
  • 41.
    세로 순서 • 함수호출의 종속성은 아래 방향으로 유지한다. • 호출되는 함수를 호출하는 함수보다 나중에 배치한다.
  • 42.
    가로 공백과 밀집도 •가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한 다. • 할당문에 공백을 주어 왼쪽/오른쪽 요소를 확실히 나눌 수 있고, • 함수이름과 괄호는 밀접하기에 공백을 넣지 않는다. Int lineSize = line.length() Private void measureLine(String line)
  • 43.
    들여 쓰기 • 간단한if문, while문, 함수에서 들여쓰기를 무시하고 싶은 충동 을 이겨내라! Public String render() {return “”;} Public String render() { return “”; }
  • 44.
    팀 규칙 • 팀은한 가지 규칙에 합의해야 한다. 그리고 모든 팀원이 그 규 칙을 따라야 한다. • 한 소스파일에서 봤던 형식이 다른 소스파일에서도 쓰이리라는 생각을 갖게 해야 한다.