Lee's Grow up

[독서리뷰] 클린코드 본문

일상/독서

[독서리뷰] 클린코드

효기로그 2020. 4. 3. 14:11
반응형

1. 깨끗한 코드

일정? 압박? 어떠한 이유로든 지저분한 코드를 지양하고, 깨끗한 코드를 만들려고 노력하라
깨긋한 코드 : 가독성이 좋으며, 적당히 추상적이며 최소한의 일을 하고 중복이 적어야함

2. 의미 있는 이름

  • 메소드, 변수 클래스 등 이름이라는 방법으로 최소한의 정보를 '정확'하게 전달해야 한다.
  • 여러개의 목록일 경우 실제 list에 담는게 아니라면 accountList 같이 list라는 예약어를 쓰지말고, accounts 등으로 명명
  • 불용어를 피하며, getCustomer(), getCustomerInfo()와 같이 구분이 불분명하게 사용을 피하라
  • 인코딩을 피해라.. 단 인터페이스나 구체 클래스의 경우 imp정도는 사용하는게 가독성이 좋음.
  • 클래스명은 명사나 명사구, Data, Info같은 포괄적인 단어는 피하고 동사 사용 금지
  • 동사구를 사용 save, delete 등등..
  • 한 개념에 한 단어를 사용 같은 메소드를 클래스마다 get, fetch 등 다르게 사용 하면 헷갈린다
  • 적절한 접두어 사용
  • 불필요한 맥락을 제거
  • 해법 영역 즉 silgleton 같이 친숙한 용어 사용 권장
결론 : 변수명이든, 클래스명이든, 함수명이든 이름이 중요하다

3. 함수

  • 함수는 한 가지를 해야 한다. 그 한가지를 잘 해야 한다. 그 한 가지만을 해야 한다.
    • 함수 당 추상화 수준은 하나로, 추상화 수준이 높은 함수의 경우 다른 함수도 높은 수준의 추상화를 구현해야 한다
      ex) getHtml()은 상당히 높은 추상화 이와 같은 함수를 사용하는대 동시에 .append()와 같은 낲은 수준의 추상화를 같이 사용하지 말라.. 이러면 읽는 사람이 개념인지 세부사항을 구현한 함수인지 구분하기 어려워진다.
    • 부수효과를 발생하지 말아라
  • 위에서 아래로 -> 추상화 수준이 낮아지는 방식으로 이야기를 읽듯이 구현
  • 모듈내에서 함수 이름은 같은 문구, 명사, 동사를 사용한다
  • 인수는 0개가 이상적.그 다음이 1,2, 3이상부터는 가능하면 피하는게 좋다 4는 특별한 이유 아니고선 무조건 피하기
    • 인수가 많아질수록 독자가 함수 파악이 어려워진다. ex render(boolean isSuite) 보다는 renderForSuite()가 한눈에 보기 편함
  • 인수가 많아지면, 클래스로 만드는 방법을 고려해봐라
  • 객체 상태를 변경하거나, 객체 정보를 반환하거나 둘 중 하나이다. 둘다 사용하면 안된다.
  • 오류코드구문 if로 구분하지말고 try-catch로 구분
  • 반복하지 말아라.
  • 함수는 동사, 클래스는 명사
결론 : 이유불문, 함수는 최대한 작게 만들어라, 구현이 아니라 어떻게 풀어갈지 잘 서술하는 느낌으로 설계하라

4. 주석

  • 주석은 실패한코드, 잘 작성한 코드는 그 자체로 의도가 분명하다.
  • 프로그램은 변화하는데 그에 맞게 주석을 관리하기란 현실적으로 불가능! 그래서 주석은 최대한 피해라.
  • 그렇다면 좋은 주석은? 저작권라이센스, 정규식 설명, 의도 설명, TODO주석 Javadocs 등
  • 나쁜 주석은? 의무적 주석, 이력 주석, 닫히는 구문에 주석, 기본적인 설명 주석 등
결론 : 주석은 불필요하다. 단 필요한 경우도 존재하니 필요할때만 작성

5. 형식 맞추기

  • 적절한 행 길이를 유지하라.일반적으로 짧을수록 이해하기가 편하다.
  • 개념은 빈 행으로 분리해라 함수와 함수, 패키지와 클래스명 등등
  • 개념있는 관계는 세로로 밀집시켜라
  • 연관 관계의 함수끼리는 세로거리로 연관성을 표현한다 -> protected 변수를 피해야 하는 이유중 하나.. 부모 클래스를 가봐야 하니까
  • 변수선언은 사용하는 위치에 최대한 가까우 곳에 선언, 인스턴스는 클래스 맨 처음에
  • 가로 정렬은 기본적으로 강조의 의미가 불분명해져서 불필요.. 멤버가 길어지면 클래스를 쪼개는것을 고려
  • 팀 규칙이 있다면 결국 그게 규칙이다.
결론 : 형식을 맞춰서 가독성이 좋은 코드를 작성해야 한다.

객체와 자료 구조

자료구조나 알고리즘의 경우 객체보단 절차적인 클래스가 좀 더 효율적

결론 : 새로운 타입을 추가하는 유연성이 필요하면 객체로, 새로운 동작이 추가되는 유연셩이 필요하면 자료 구조와 절차적인 코드가 더 적합하다.

오류 처리

깨긋한 코드는 읽기도 중요하지만, 안정성도 높아야 한다. 오류 처리와 프로그램 논리를 분리하면 유지보수성이 크게 높아진다.

경계

경계에 위치하는 코드는 깔끔하게 분리, 테스트 케이스를 작성해둔다. 우리쪽 에서 외부 패키지를 자세하게 알 필요가 없다. 통제 불가능한 외부 api 대신 통제 가능한 내부에 의존하는게 좋다. 외부 패키지 호출코드를 줄여 경계를 관리하자. wrapper로 감싸거나 adapter 패턴을 사용해 우리가 원하는 인터페이스를 패키지가 제공하는 인터페이스로 변환하자.

단위 테스트

  1. 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
  2. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
  3. 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.

테스트의 F.I.R.S.T 5가지 조건

  1. Fast 빨라야 한다. 테스트가 느리면 테스트를 돌리기 부담스러움 -> 코드 품질 엉망으로 이어진다.
  2. Independent 독립적이어야 한다. 각 테스트는 독립적이고 어떤 순서로 실행해도 상관 없어야 한다.
  3. Repeatable 반복 가능하게 : QA호ㅓㅏㄴ경, 인터넷 환경에 상관없이 실행할 수 있어야 한다.
  4. Self-Validating 자가 검증하는 : 테스트는 bool 값으로 결과를 내야한다. 성공아니면 실패
  5. Timely 적시에 : 테스트는 적시에 작성해야한다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다.

클래스

  • 클래스는 작아야한다. 함수에서의 작아야 한다는 의미가 아니라 단일 책임의 원칙을 지켜야 한다.
    • 얼만큼 작아야 하나? 함수는 물리적인 행 수로 크기를 측정했다면, 클래스는 맡은 책임을 센다.
    • 그렇다면 단일 책임이란 무엇인가? 클래스나 모듈을 변경할 이유가 하나뿐이어야 한다는 원칙이다.
  • 인터페이스를 사용한 변경으로부터 격리 사용하기, 외부 API를 받아올때 바로 사용하지말고 하나의 인터페이스를 두어서 호출

창발적 설계로 깔끔한 코드를 구현

  • 모든 테스트를 실행한다.
  • 중복을 없앤다.
  • 프로그래머의 의도를 표현한다.
  • 클래스와 메서드 수를 최소로 줄인다.

위에서부터 중요도 순서

살아있는 프로그램

그저 돌아가는 코드가 아닌, 점진적으로 개선하는 코드를 작성해라. 한번에 완벽한 프로그램을 만들 필요는 없다.
점점 개선해 나가면 된다. 저자는 테스트주도 개발을 기반으로 코드를 계속 리팩토링해 나간다.

마무리

책의 마지막 부분에는 실제 사례를 통해서 위 이론들을 어떻게 풀어가는지에 대해 자세히 나와있다.
책에는 위 내용 말고도 더 자세히 많은 내용이 담겨있으니, 깨긋한 코드란 무엇인지 고민해보고 싶은 사람이라면
한번쯤 아니 두번 세번 읽어봐야할 책인 것 같다.

반응형
Comments