• 깔끔하게 보기 좋은 코드를 만들자.
  • 간단한 규칙을 정하고 규칙을 착실히 따라야 한다.
  • 팀으로 일한다면 팀이 합의해 규칙을 정하고 모두가 따라야한다.
  • 자동으로 적용하는 도구를 활용하자.
  • ( 우리회사는 구글 형식맞추는거 사용 )
  1. 형식을 맞추는 목적

    • 코드의 형식은 중요하다 너무중요하다.
  2. 적절한 행길이를 유지하라

    • 클래스 하나가 500줄을 넘지 않고 대부분 200줄로만 짜고도

    • 커다란 시스템을 구축할수 있다.

    • 일반적으로 큰파일보다 작은파일이 이해하기가 쉽다.

    • 신문기사 처럼 작성하라.

      • 이름은 간단하면서도 설명이 가능하게 짓는다.
      • 이름만 보고도 올바른 모듈을 살펴보고 있는지 아닌지를 판단할 정도로 신경 써서 짓는다.
      • 소스 파일 첫부분은 고차원 개념과 알고리즘을 설명한다.
      • 아래로 내려갈수록 의도를 세세하게 묘사한다.
      • 마지막에는 가장 저차원 함수와 세부내역이 나온다.
    • 개념은 빈행으로 분리하다.

      • 거의 모든 코드는 왼쪽에서 오른쪽 그리고 위에서 아래쪽으로 읽힌다.
      • 각 행은 수식이나 절을 나타내고, 일련의 행 묶음은 완결된 생각 하나를 표현한다.
      • 생각 하나 사이에는 빈 행을 넣어 분리해야 마땅하다.
      • 빈 행은 새로운 개념을 시작한다는 시각적 단서다.
      • ( 말 멋있다. )
    • 세로 밀집도

      • 줄바꿈이 개념을 분리 한다면 세로 밀집도는 연관성을 의미한다.
      • 즉 서로 밀집한 코드행은 세로로 가까이 놓여야 한다는 뜻이다.
      • 변수나 일급컬렉션 메소드 이 3개도 붙여야된다. 연관되어있다면.
    • 수직거리

      • 서로 밀집한 개념들은 세로로 가까이 둬야 한다.
      • 서로 밀집한 개념들은 한파일에 속해야 마땅하다.
      • protected 변수를 피해야 되는 이유.
      • ( protected 변수를 쓰면 같은 패키지내에서 쓸수 있으니까. )
    • 변수선언

      • 변수는 사용하는 위치에 최대한 가까이 선언한다.
      • 루프문을 제어하는 변수는 흔히 루프 문 내부에 선언한다.
    • 인스턴스 변수

      • 반면 인스턴스 변수는 클래스 맨 처음에 선언한다.
      • 변수간에 세로로 거리를 두지 않는다.
      • 잘 설계한 클래스는 많은 클래스 메서드가 인스턴스 변수를 사용하기 때문이다.
    • 종속 함수

      • 한 함수가 다른 함수를 호출 한다면 두 함수는 세로로 가까이 배치한다.
      • 또한 그낭하다면 호출하는 함수를 호출되는 함수보다 먼저 배치한다.
      • 첫째 함수에서 호출하는 첫번째 함수가 바로 아래 정의된다.
      • 그다음은 그아래 정의된다.
      • 그러므로 호출되는 함수를 찾기가 쉬워지며 그만큼 모듈 전체의 가독성도 높아진다.
    • 개념의 유사성

      • 비슷한 동작을 수행하는 일군의 함수들
      • 명명법이 비슷하고 기본 기능이 유사한것들
      • 종속적인 관계가 없더라도 가까이에 배치해야될 함수
    • 세로 순서

      • ( 좀 어렵다 )
      • 호출되는 함수를 호출하는 함수보다 나중에 배치한다.
      • 그러면 소스코드 모듈이 고차원에서 저차원으로 자연스럽게 내려간다.
    • 가로형식 맞추기

      • 한 행은 가로로 얼마나 길어야 적당할까 ?
      • 글쓴이 할아버지는 120자정도로 행길이를 제한함.
    • 가로 공백과 밀집도

      • aa(String a)
      • 이것처럼 함수안에 인자는 괄호 사이에 공백을 넣지 말자.
      • 여러개일경우는 우선순위를 강조하기 위해서 공백을 사용한다.
      • 연산자 ( + - 같은것들 ) 은 우선순위 강조를 위해 띄어 쓴다.
    • 가로 정렬

      • 선언문과 할당문을 별도로 정렬하면 보기가 안좋다
      • 예) String a;
      • 예) Long b;
      • 예) Integer c;
      • 정렬이 필요할 정도로 목록이 길다면 클래스를 쪼개야 된다는 의미다.
    • 들여쓰기

      • 범위로 이루어진 계층을 표현하기 위해 우리는 코드를 들여 쓴다.
      • 들여쓰는 정도는 계층에서 코드가 자리잡은 수준에 비례한다.
      • 클래스 정의처럼 파일 수준인 문장은 들여 쓰지 않는다.
      • 클래스 내 메서드는 클래스보다 한 수준 들여 쓴다.
      • 메서드 코드는 메서드 선언보다 한 수준 들여 쓴다.
      • 블록 코드는 블록을 포함하는 코드보다 한 수준 들여 쓴다.
    • 들여쓰기 무시하기

      • 간단한 if문 짧은 while문 짧은 함수에서 들여쓰기 규칙을 무시하면 안된다.
      • 한행에 범위를 뭉뚱그린 코드를 피한다
      • 예) public String render() throws Exception { return ""; }
    • 가짜 범위

      • 때로는 빈 while문이나 for문을 접한다.
      • 제대로 들여쓰기해서 써줘라.
    • 팀 규칙

      • 팀이 규칙을 정했으면 팀원은 그 규칙을 정해야 한다.

'book > 클린코드' 카테고리의 다른 글

7장 - 오류처리  (0) 2020.11.27
6장 - 객체와 자료구조  (0) 2020.11.25
4장 - 주석  (0) 2020.11.22
3장 - 함수  (0) 2020.11.19
2장 - 의미있는 이름들  (0) 2020.11.17

개요

  • 주석은 잘달리면 유용하다.

  • 쓸데없는 주석이나 조잡한 주석은 거짓과 잘못된 정보를 퍼뜨려 해악을 미친다.

  • 주석을 쓴다는 것은 내가 코드를 잘 설명한다는것에 실패했다는 의미.

  • 왜냐면 그것을 보완하는 설명을 주석으로 쓰는것이니까.

  • 주석은 오래될수록 코드랑 멀어진다. 오래될수록 완전히 잘못될 가능성도 높아진다.

  1. 주석은 나쁜 코드를 보완하지 못한다.
  • 주석 달아도 코드 그지같은건 그지같은거니까 코드 그지같은거나 고쳐라
  1. 코드로 의도를 표현하라.
  • 주석으로 달려는 설명도 코드로 충분히 표현할수 있다.
  1. 좋은 주석
  • 어떤 주석은 필요하거나 유익하다.

  • 하지만 정말 좋은 주석은 주석을 달지 않을 방법을 찾아낸 주석이란것을.

  • 법적인 주석

    • 회사가 정립한 구현 표준에 맞춰 특정 주석을 넣으라고 명시한다.
    • 이럴 경우 사용한다.
    • 그리고 각 소스 파일 첫머리에 주석으로 들어가는 저작권 정보와 소유권 정보는 필요하고도 타당하다.
    • ( 쓰레기라더니 좋게말함 ㅋㅋ)
  • 정보를 제공하는 주석

    • 추상 메서드가 반환할 값을 설명할 경우
      • 하지만 가능하다면 함수 이름에 정보를 담자.
    • 정규표현식이 시각과 날짜를 뜻하는 경우를 주석으로 표현할때
    • 이럴 경우는 시각과 날짜를 변환하는 클래스를 만들어 코드를 옮겨주면 더 깔끔해지고
    • 주석이 필요 없어진다.
  • 의도를 설명하는 주석

    • 때떄로 주석은 이해하게 도와주는 선을 넘어 결정에 깔린 의도까지 설명한다.
  • 의미를 명료하게 밝히는 주석

    • 인수나 반환값이 표준 라이브러리나 변경하지 못하는 코드에 속한다면 의미를 명료하게 밝히는 주석이 유용하다.
    • 그릇된 주석을 달 확률도 높아진다.
    • 그래서 주석을 검증하기가 쉽지가 않으므로 고민하고 사용하도록 한다.
  • 결과를 경고하는 주석

    • 테스트케이스를 실행하면 안될 경우 사용하는 주석

    • 이럴떈 @Ignore 애노테이션을 사용 하자. 예) @Ignore("시간이 오래걸리니까 쓰지마세요")

    • //쓰레드에 안전하지 못하다.

    • //그래서 각 인스턴스를 독립적으로 생성해야 된다.

    • 위와 같은 주석이 아주 합리적이다.

    • 쓰레드를 정적으로 초기화 시켜서 사용할수도 있는데 이 주석을 보고 실수를 면한다.

  • Todo 주석

    • 때로는 앞으로 할일을 주석으로 남겨두면 편하다.
    • 함수를 구현하지 않은 이유와 미래 모습을 Todo 주석으로 설명할수 있다.
    • 당장 필요하지도 않고 구현하기가 쉽지 않은 것들을 써논다.
    • 하지만 TOdo 코드로 떡칠하는건 좋지 않다.
    • 주기적으로 Todo 주석을 점검해 없애도 괜찮은 주석은 없애자.
  • 중요성을 강조하는 주석

    • 대수롭지 않다고 여겨질 뭔가의 중요성을 강조하기 위해 주석을 사용한다.
    • ( 이건 나쁘다 좋다 별말이 없다 )
  • 공개 API에서 javadocs

    • 설명이 잘 된 공개 API는 참으로 유용하고 만족스럽다.
    • 특히 표준 자바 라이브러리에서 사용한 javadocs가 좋은 예다.
    • 공개 API를 구현한다면 javadocs를 아주 잘써야된다.
  1. 나쁜주석
  • 대다수 주석이 이 범주에 속한다.

  • 쓸데없이 주절거리는 주석

    • 자기만 이해하는 주석은 낭비다.
  • 같은 이야기를 중복하는 주석

    • 알기쉬운 코드를 그대로 주석으로 옮겨논것
    • 간단하거나 다 아는것들을 쓸데없이 여러번 쓰는것
    • 이건 예제를 봐야됨. 목록 4-2 ContainerBase.java
  • 오해할 여지가 있는 주석

    • 오해할 여지조차 주게 하면 안된다.
  • 의무적으로 다는 주석

    • 모든 함수에 javadocs를 넣으라는 규칙 같은건 하면 안된다.
  • 이력을 기록하는 주석

    • 이젠 git같은 소스관리 시스템같은게 있으니까 그만달자.
  • 있으나 마나 한 주석

    • 이런건 쓰지말자.
    • 예) 기본생성자
  • 무서운 잡음

    • 변수명과 동일한 주석
    • ( 진짜 똑같음 )
  • 함수나 변수로 표현할수 있다면 주석을 달지마라

  • 위치를 표시하는 주석

    • 가독성이 구려지므로 특히 뒷부분에 슬래쉬 ex ) //////// 이런식으로 끝나는 잡음은 제거하는 편이 좋다.
    • 진짜 필요할떄만 아주 드물게 사용해라
  • 닫는 괄호에 다는 주석

    • } // try
    • 위처럼 닫는 괄호에 주석 다는대신 함수를 줄이려고 시도해라.
  • 공로를 돌리거나 저자를 표시하는 주석

    • 이제 git과 같은 소스코드 관리시스템이 있으므로 지워라
  • 주석으로 처리한 코드

    • 주석으로 처리된 코드는 다른 사람들이 지우기를 주저한다.
    • 그냥 지워라.
    • git이 기억해준다.
  • HTML 주석

    • 혐오 그자체다
    • 도구로 주석을 뽑아 웹페이지에 올릴 작정이라면 그건 도구가 해야할일이다.
  • 전역정보

    • 주석을 달아야 한다면 근처에 있는 코드만 써라
    • 코드 일부에 주석을 달면서 시스템의 전반적인 정보를 쓰지마라.
    • 왜냐면 시스템 어딘가에 있는것들을 설명한것인데 그것이 어딨는지 읽는사람은 전혀 모르니까.
  • 너무 많은 정보

    • 주석에다 흥미로운 역사나 관련 없는 정보를 쓰지마라.
  • 모호한 관계

    • 주석과 주석이 설명하는 코드는 둘사이의 관계가 명백해야 한다.
    • 주석자체가 다시 설명을 요구해선 안된다.
  • 함수 헤더

    • 짧은 함수는 긴 설명이 필요없다.
    • 함수를 짧고 한가지만 수행하도록 만들며 함수에 이름 잘붙여라 함수헤더같은거 쓰지말고
  • 비공개 코드에서 javadocs

    • 공개하지 않을거면 쓸모가 없다.

'book > 클린코드' 카테고리의 다른 글

7장 - 오류처리  (0) 2020.11.27
6장 - 객체와 자료구조  (0) 2020.11.25
5장 - 형식 맞추기  (0) 2020.11.23
3장 - 함수  (0) 2020.11.19
2장 - 의미있는 이름들  (0) 2020.11.17

함수를 어떻게 만들어야 처음보는 사람이 쉽게 이해할까 ?

  1. 작게 만들어라.

    • 최대한 작게만들어서 그 함수가 무슨 역할을 하는지 알수 있게 만든다.
  2. 함수는 한가지 일만 해야한다.

    • 그래야 명확하게 그 함수가 무슨역할인지 알수 있으니까.
    • 한가지 일은 추상화 수준이 하나인 단계
      • 같은 추상화 단계에서 일하는 것들이 모여있으면 이것은 한가지일만 하는것
      • 추상화 수준이란 무엇일까 ?
        • nested하게 내려가거나 올라가지 않고 같은 레이어에서 작동하는것.
      • 함수당 추상화 수준은 하나로 하자.
  3. 코드는 소설책같은것들 처럼 위에서 아래로 읽혔을때 잘 읽혀야 한다.

  • 내려가기 규칙
  • 아래로 내려갈수록 추상화 단계가 한단계 씩 낮은 함수가 온다.
  • 아래로 갈수록 상위 함수에서 나온 함수를 설명하는 느낌으로 간다.
    • 예를 들어 상위 함수에서 쓴 함수를 하위에 바로 붙여서 쓰는식으로.
  1. Switch 문
  • 추상 팩토리 ( abstract factory ) 에 숨겨서 사용한다.
  • 예제를 좀더 봐야겠다. 어렵다.
  1. 서술적인 이름을 사용하라!
  • 이름이 길어도 된다.
  • 작은기능을 가진 함수는 이름짓기도 쉽다.
  • 일관성 있게 이름을 지어라.
  • include블라블라
  1. 함수 인수
  • 이상적인 인수는 0개

    • 그다음 1개, 그다음 2개
    • 3개는 가능한 피하는 편이 좋다.
    • 4개이상은 특별한 이유가 필요하다.
    • 4개 이상은 이유가 있어도 거의 사용하면 안된다.
  • void일때 인수 받는건 가급적 피해라.

  • 플래그인수 ( boolean 값과 비슷한 체크용 인수 ) 이거 될수있음 쓰지마라

  • 인수 두개 받을때 될수있으면 writeField(outStream, name) 일 경우

  • writeField를 outStream에 합류시켜서

  • outStream.writeField(name) 으로 하나의 인수만 넣도록 하자.

  • 삼항함수는 신중히 고려해서 하도록 하자.

  • 인수가 2~3개일때 일부를 독자적인 class화 시켜서 class 변수로 선언하는 방법도 있다.

    • 대신 인수가 연관관계나 비슷한 관계여야함.
    • 그래야 줄였을경우 인수에 대한 개념을 표현할수 있으니까.
  • 단항함수 일때 함수와 인수가 동사/명사 쌍을 이뤄야 한다.

    • 이때 메소드 이름은 write(name) 보단 writeField(name) 를 사용해서
    • name이 field라는 사실이 드러나게 한다.
  • 그리고 함수이름에 키워드를 추가하는 형식도 있다.

  • 즉 함수이름에 인수이름을 넣는다.

    • assertEquals 보단 assertExpectedEqualsActual(expected, actual)이 더 좋다.
    • 그러면 인수 순서를 기억할 필요가 없어진다.
  1. 부수효과를 일으키지 마라.
  • 함수에서 하나의 기능만 사용한다고 약속하고서 남몰래 다른짓을 하지말자.

  • 때로는 예상치 못하게 클래스 변수를 수정한다.

  • 떄로는 함수로 넘어온 인수나 시스템 전역 변수를 수정한다.

  • 어느쪽이든 교활하고 해로운짓이다.

  • 예제를 보면 이해하기가 쉽다.

  • 일반적으로 출력 인수를 피해야 한다.

  • 함수가 상태를 변경해야 한다면 웬만하면 함수가 속한 객체에서 변경시키자

  • 예제를 보면 이해하기가 쉽다.

  1. 명령과 조회를 분리하라
  • 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘중 하나만 해야 한다.
  • 둘다하면 안된다.
  • 객체 상태를 변경하거나 아니면 객체 정보를 반환하거나 둘중 하나다.
  1. 오류 코드보다 예외를 사용하라
  • 명령 함수에서 오류코드를 반환하는 방식은 명령 조회 분리 규칙을 미묘하게 위반한다.

  • 오류코드를 반환하면 호출자는 오류코드를 곧바로 처리해야되는 문제에 부딪힌다.

    • Try/Catch 블록 뽑아내기
    • try/catch 블록도 별도의 함수로 뽑아내는 편이 좋다.
  • 오류 처리도 한가지 작업이다.

  • 함수는 한가지 작업만 해야한다. 결국 오류처리도 한가지 작업에 속한다.

  • try가 있다면 try로 시작해 catch finally문으로 끝내야 된다는 말이다.

  • Errorjava 의존성 자석

  • 오류 코드를 반환한다는 이야기는 클래스든 열거형 변수든 어디선가 오류 코드를 정의한다는 뜻이다.

  • 그래서 오류코드대신 익셉션을 반환해라.

  1. 반복하지마라
  • 중복 없애라
  • 반복 하지마라
  1. 구조적 프로그래밍
  • 모든 함수와 모든 함수내 블록에는 입구와 출구가 하나씩만 존재해야된다.
  • 즉 함수는 return문이 하나여야 한다.

'book > 클린코드' 카테고리의 다른 글

7장 - 오류처리  (0) 2020.11.27
6장 - 객체와 자료구조  (0) 2020.11.25
5장 - 형식 맞추기  (0) 2020.11.23
4장 - 주석  (0) 2020.11.22
2장 - 의미있는 이름들  (0) 2020.11.17

이름을 잘짓자.

변수명을 잘짓자

  • 이름을 잘지으면 단순히 코드만 보고도 무슨 기능을 하는지 다 알수 있다.

  • 컨테이너 가 list라도 실제 컨테이너 유형을 이름에 넣지 않는게 바람직하다.

  • 일관성 있게 이름지어라

  • 이름 지을때 내 의도를 읽는사람이 알수 있게 하자.

  • 의미없는 단어를 넣지마라

  • pruduct란 클래스가 있을 경우 다른 클래스를 productInfo 나 productData라고 쓰지말자

  • 이건 개념을 구분하지 않은채 이름만 달리한 경우이다.

  • data나 info는 의미가 불분명한 불용어다.

  • 관례가 없다면 읽는사람은 product나 productInfo의 차이를 모를것이다.

  • 발음하기 쉽게 지어라

  • 그래야 기억하기도 쉽다.

  • 소스를 검색할때 검색이 잘되게 지어라.

  • 그래야 찾기도 쉬우니까.

  • 이름에 인코딩하지마라

  • 내 생각. (이런걸하는 제정신인 사람이 있는가 ? 암호화 시키는것이면 몰라도..)

  • 변수명에 type을 집어넣었을경우 변수의 type이 바꼈을때 변수명은 그대로 String이므로 변수명에 타입은 쓰지말자.

  • 접두어 쓰지말자.

  • 인터페이스에 접두어 I같은것을 넣지 않는것이 좋다고 생각한다 ( 작가생각 )

  • 구현클래스에는 impl 같은것을 붙이거나 앞에 C를 붙이는것이 인터페이스에 접두어 넣는것보다 좋다고 생각한다고 작가는 말한다.

  • for문의 반복변수 ijk까진 가능하다 근데 L은 절대 쓰지말라고한다

  • 클래스의 이름은 명사나 명사구가 적합하다.

  • manager processor data info 등과 같은 단어를 피하고 동사를 사용하지 않는다.

  • 메서드이름은 동사나 동사구가 적합하다.

  • postPayment, deletePage, save 등이 좋은 예

  • 접근자 변경자 조건자 는 javabean 표준에 따라 앞에 get , set , is를 붙인다.

    • 이 메소드는 데이터형 클래스에서 값 가져오거나 설정하거나 값 true false 체크할떄 쓰는그거같음
  • 생성자를 중복정의 할때는 정적 팩토리 메서드를 사용한다.

  • 메서드는 인수를 설명하는 이름을 사용한다.

  • 예)

  • 1번 ) Complex fulcrumPoint = Complex.FromRealNumber(23.0);

  • 2번 ) Complex fulcrumPoint = new Complex(23.0);

  • 1번소스가 2번소스보다 좋다.

  • 2번소스를 사용하지 못하게 할려면 생성자를 private이나 protect를 걸어버리자

  • 단 protect는 같은 패키지안에서 사용될수 있으므로 같은패키지안에서도 싫으면 private쓰자.

  • 의도를 분명하고 솔직하게 표현해라

  • 이상한 농담같은거나 기발한것들은 피하자.

  • 비슷한단어를 클래스들마다 다르게 쓰지말자 메소드도 마찬가지고

  • 일관성있게 이름짓자 get이면 get으로 다 통일 controller면 다 controller로

  • 하지만 위처럼 쓰라고했다고 기능이 다른데도 같게 쓰면 문제있는것이다.

  • 기능과 이름의 일관성을 유지하라.

  • 해법영역에서 가져온 이름을 사용해라.

    • 대충 전산용어 알고리즘이름 패턴이름 수학용어등을 사용해도 괜찮다는 뜻.
  • 적절한 프로그램용어가 없다면 문제영역에서 가져와야한다.

  • 클래스 내부에 firstName , lastName , street , city , state란 변수가 있을때

  • 한 메소드에서 state란 변수를 사용했을때 이 변수가 어떤 클래스의 일부라는 사실을 알수 있을까 ?

  • 클래스의 일부가 아니더라도 위에것들은 address와 관련된 것들이다.

  • 이 state란 변수가 address와 관련된것인걸 알수 있을까 ?

  • 모르기 때문에 state 앞에 addr이라는 접두어를 붙인다.

  • addrState

  • 공통으로 사용된 변수들의 연관관계를 알수 있게 앞에 접두어를 붙여주거나

  • 클래스 함수 이름 공간에 넣어 맥락을 부여한다.

  • 모든 방법이 실패했을때만 접두어를 넣어준다.

  • 예제를 보면 이해가 쉬워진다.

  • Gas Station Deluxe 라는 앱을 만든다고 가정했을떄 모든클래스의 이름을 GSD로 시작하겠다는것은 미친짓이다.

  • 의미가 분명한 경우에 한해 짧은이름이 더 좋다.

  • accountAddress와 customerAddress는 Address 클래스 인스턴스로는 좋은 의미이지만

  • 클래스이름으로는 별로다.

  • Address가 클래스 이름으로 적합하다.

  • 주소를 port mac, web으로 구분지어야 한다면

  • postalAddress, Mac , Url이란 이름도 괜찮다. 그러면 의미가 분명해진다.

결론 이름 잘지어라

'book > 클린코드' 카테고리의 다른 글

7장 - 오류처리  (0) 2020.11.27
6장 - 객체와 자료구조  (0) 2020.11.25
5장 - 형식 맞추기  (0) 2020.11.23
4장 - 주석  (0) 2020.11.22
3장 - 함수  (0) 2020.11.19

2020년 4월 16일 

 

자바의정석 3.0

이펙티브 자바

오브젝트

리팩토링

클린코드

자바 병렬 프로그래밍

그림으로 배우는 HTTP & Network

HTTP 완벽 가이드
DevOps와 SE를 위한 리눅스 커널 이야기
자바 8 인 액션
테스트 주도 개발
자바 ORM 표준 JPA 프로그래밍
토비 스프링

나는 line 개발자

스프링부트와 AWS로 혼자 구현하는 웹서비스

객체지향의 사실과 오해

스프링 입문을 위한 자바 객체 지향의 원리와 이해

시작하세요! 도커/쿠버네티스
도커/쿠버네티스를 활용한 컨테이너 개발 실전 입문

+ Recent posts