[Clean Code] Ch.1 깨끗한 코드 ~ Ch.2 의미 있는 이름

ByWindow·2022년 6월 24일
0

CleanCode

목록 보기
1/1

깨끗한 코드

코드는 항상 존재한다

코드는 요구사항을 상세히 표현하는 수단이자 언어이므로, 앞으로 코드가 사라질 가망은 전혀 없다.
현재 개발자의 역할을 기계가 대신 한다면 ,추상화도 불가능할 뿐더러 기계가 실행할 정도로 상세하게 요구사항을 작성해야 되는데 이런 작업이 바로 프로그래밍이고 이렇게 명시한 결과가 코드이다.

르블랑의 법칙 (leblanc’s law)

나중은 절대 돌아오지 않는다

프로그램을 개발할 때 시간에 쫓기느라 “기획대로 돌아가는 코드" 그 이상도 그 이하도 아닌 개발을 할 때가 있었다.
인턴 때도 아키텍처나 디자인패턴을 충분히 이해하고 적용한 개발을 하지 않았기 때문에 “나쁜 코드”를 작성한 경우가 많았다. 그때 개발팀의 주임님 및 팀장님께 죄송한 마음뿐이다…
이렇게 나쁜 코드가 쌓일수록 팀의 생산성이 저하될 뿐만 아니라 프로젝트 전체를 봤을 때 깨끗한 코드를 작성하는 경우보다 더 많은 자원을 할애하게 한다.
따라서 언제나 코드를 깨끗하게 유지하는 습관이 필요하다!

이번에 진행하는 프로젝트에서는 이렇게 깨끗한 코드를 유지하며 개발하도록 노력할 것이다.

깨끗한 코드란?

  • 보는 사람에게 즐거움을 선사하는 코드
  • 속도 및 HW 자원 측면에서 효율적인 코드
  • 세세한 사항 및 오류까지 처리하는 코드
  • 한가지 일만 처리하도록 설계된 코드
  • 설계자의 의도를 숨기지 않는 코드
  • 사실에 기반하고 필요한 내용만 담은 코드
  • 최소한의 의존성으로, 그것이 명확히 정의된 코드
  • 다른 사람도 읽기 쉽도록 가독성이 뛰어난 코드
  • 중복이 없는 코드 (DRY)

의미있는 이름

코드를 작성하다보면 이름을 붙여야 될 것이 많다. 변수, 함수, 클래스, 패키지를 비롯해 소스파일이나 디렉토리에도 이름을 붙인다.
이름을 지을 때 몇 가지 규칙을 정해서 팀 내에서 통일시켜야 한다.

의도를 분명히 해라

변수나 함수, 클래스 이름은 1.코드의 존재이유, 2.수행기능, 3.사용방법 에 모두 답할 수 있을 정도로 의도를 분명하게 밝혀야 한다.
이런 질문에 따로 주석을 달아서 답해야 한다면, 좋은 이름이라고 할 수 없다.

변수를 선언할 때를 예로 들어,
정수형 변수라고 해서 단순히 i 혹은 d로 변수명을 정하는 것이 아니라
그 변수가 어떤 수를 담는 것인지 명확하게 나타내야 한다.
생성일로부터 경과한 날짜를 저장하는 변수라고 한다면, daysSinceCreation 이렇게 말이다.

그릇된 정보는 피하라

그릇된 단서는 코드의 의미를 흐리기 때문에, 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해도 안되며 오해의 소지가 있는 단어를 사용해서도 안된다.

여러 계정을 그룹으로 묶을 때, List라는 단어를 사용해서 이름을 짓지 않는다. 컨테이너가 List 유형이든 아니든 간에 컨테이너 유형을 이름에 넣지 않고 accountGroup 혹은 bunchOfAccount 라고 명명하는 것이 옳다.

또한, 서로 흡사한 이름을 사용하지 않도록 주의해야 한다. 많은 단어가 결합된 형태의 이름에서 단어 하나만 다른 경우가 이에 해당한다.

의미 있게 구분하라

컴파일러와 인터프리터만 통과하려는 생각으로 코드하면 안된다.

나는 정보를 조회하는 함수를 명명할 때, 주로 info라는 키워드를 넣어서 사용했었다. 하지만 이런 방법은 좋지 못한 방법이다.
고객의 정보를 조회할 때, customer와 customerInfo 이렇게 두 함수가 있다면 무슨 함수를 호출 해야 할지 명확히 구분하는 것이 어렵다.

발음하기 쉬운 이름을 사용하라

프로그래밍도 사회활동이다. 회의 및 코드리뷰를 진행하다보면 명명한 이름을 발음해야되는 경우가 많다.
그런 경우에 발음하기 어려운 단어들로 조합된 이름을 말한다고 하면 그 자체도 어려운 일이 될 것이다.
따라서, timestampmdhms와 같이 적는 일은 피해야한다.

검색하기 쉬운 이름을 사용하라

문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다.
간단한 메서드에서 로컨 변수만 한 문자를 사용하고, 이름의 길이는 범위의 크기에 비례해야 한다.
변수나 상수를 코드 여러 곳에서 사용한다면 검색하기 쉬운 이름이 적합하다.
이름을 의미있게 지으면 함수가 그만큼 길어지지만, 찾기 쉬운 이름을 사용할 때의 이점이 더 크다.

인코딩을 피하라

변수명에 타입을 명시하는 헝가리식 표기법이나 멤버 변수 접두어 m_를 사용하는 것은 옳지 않다. 이것은 컴파일러가 발전하지 않았을 당시 개발자가 타입을 기억하기 위해 사용했던 방식으로, 요즘의 코딩스타일과는 맞지 않다.
반면에, 인코딩이 필요한 경우도 있는데 인터페이스 클래스와 구현 클래스를 구별해야 될 때이다. 둘 중 하나를 인코딩 해야된다면 구현 클래스를 인코딩하는 것이 좋다. 접두사 I를 붙여 인터페이스 클래스를 인코딩하는 방식은 주의를 흐트리고 과도한 정보를 제공한다. 그리고 내가 다루는 클래스가 인터페이스라는 사실을 다른 사람에게 알리지 않는 것이 좋다.

기억력을 자랑하지 마라

코드를 읽으면서 변수명을 자신이 아는 이름으로 변환해야 한다면 바람직하지 않은 이름이다. 짧은 반복문에서 i, k, j 같은 한 글자 변수를 사용하는 것은 괜찮지만 그 외에 한 글자 변수를 사용해서 그 변수가 무엇을 의미하는 기억해야한다면 좋지 않은 이름이다. 명료함이 최고라는 것을 기억하자.

기발한 이름은 피하라

특정 문화나 영화 속에 등장하거나, 구어체나 속어를 사용해서 이름을 지으면 안된다. 의도를 분명하고 솔직하게 표현하는 것이 중요하다.

한 개념에 한 단어를 사용해라

추상적인 개념 하나에 단어 하나를 선택해라.

  • fetch, retrieve, get → 모두 동일한 의미이므로 통일해서 사용하는 것이 좋다
  • controller, driver, manager → 근본적으로 어떻게 다른 의미를 지니는지를 명확히 하고, 의미를 구별할 수 없다면 같은 단어를 사용하는 것이 좋다

다른 개념에 같은 단어를 사용하지 마라

위에서 말한 규칙을 다른 방향에서 해석한 느낌이다. 한 단어를 두가지 목적으로 사용해서는 안된다.
위의 규칙을 지켜서 여려 클래스에 add라는 메서드가 생겼다고 하자. 이때 그 모든 add 메서드의 매개변수와 반환값이 의미적으로 똑같다면 문제가 없다. 즉, 모든 메서드가 기존 값 두개를 더하거나 이어서 새로운 값을 만드는 경우는 괜찮다. 하지만 집합에 원소를 추가하는 메서드에 대해서도 add를 사용한다면, 이것은 옳지 않다. add 대신 insertappend 라는 이름이 적당하다.

solution 영역에서 가져온 이름을 사용해라

코드를 읽는 사람도 개발자이기에 전산용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다. 반드시 domain 영역에서 이름을 가져오는 정책은 현명하지 않다.

개발에 사용되는 다양한 패턴 및 CS용어들에 대한 개념을 공부하고 숙지해둬야겠다…

domain 영역에서 가져온 이름을 사용해라

적절한 프로그래밍 용어가 없다면, 그때 domain 영역에서 이름을 가져온다.
domain과 solution영역을 구분한 후, domain 영역 개념과 관련이 깊은 코드라면 domain 영역에서 이름을 가져온다.

의미있는 맥락을 추가하라

의미가 분명한 이름을 만들기 위해 클래스,함수,이름 공간에 맥락을 부여하고, 이것이 실패하면 최후의 수단으로 접두어를 붙여라.

firstName, lastName, street, houseNumber, city, state, zipcode라는 변수가 있다. 전체를 쭉 훑어보면 주소라는 사실을 알 수 있지만, state라는 변수 하나만 봤을 때는 state가 주소 일부라는 사실을 알 수 있을까?
나도 state라는 단어를 상태를 의미하는 변수명에 자주 사용했었기에 의미가 분명하지 않다.

이런 경우에 Address 라는 클래스를 생성하여 맥락을 추가하는 것이 좋은 방법이고, 해당 방법을 사용할 수 없다면 Addr 같은 접두어를 붙여야 한다.

불필요한 맥락을 없애라

Gas Station Deluxe 라는 애플리케이션을 짜는 경우에, 모든 클래스 이름을 GSD로 시작하겠다고 한다면 전혀 바람직하지 않다. 만약 그렇다면 IDE에서 G를 입력하고 자동 완성 키를 누르면 모든 클래스를 열거하게 될 것이다.
고객의 주소를 표현하는 클래스를 GSDAccountAddress로 만든 후, 나중에 다른 고객 관리 프로그램에서 고객주소가 필요한 경우를 가정한다면 해당 클래스를 사용할 수 있을까? 17 글자 중 10글자는 중복이거나 부적절하다.

의미가 분명한 경우에 한해서 짧은 이름이 긴 이름보다 좋다. 고로 불필요한 맥락을 추가하지 말자.

accountAddress나 customerAddress는 Address 클래스의 인스턴스로는 좋은 이름이지만 클래스 이름으로는 부적합하다. (반대로 Address는 클래스 이름으로 적합하다)

만약 프로그램에서 포트주소, MAC주소, 웹주소를 구분해야한다면 각각을 PostalAddress, MAC, URI라는 이름으로 만드는 것이 괜찮은 선택이다.


클래스 이름

클래스 이름과 객체 이름은 명사나 명사구가 적합하다. 동사는 사용하지 않는다.

  • 좋은 예 : Customer, WikiPage, Account, AddressParser
  • 나쁜 예 : Manager, Processor, Data, Info → 이렇게 많은 곳에서 사용되거나 의미가 모호한 단어들은 피해라

메서드 이름

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

  • 좋은 예 : postPayment, deletePage, save
  • javabean 표준을 따른다
    • 접근자(Accessor) : get을 붙인다
    • 변경자(Mutator) : set을 붙인다
    • 조건자(Predicate) : is를 붙인다

생성자를 overload할 때는 정적 팩토리 메서드를 사용하고, 메서드는 인수를 설명하는 이름을 사용한다.

Complex fulcrumPoint = Complex.FromRealNumber(23.0);

메서드 이름을 위와 같이 만들어 사용한다면, 실수로부터 Complex number를 만들어내는 메서드라는 것을 바로 파악할 수 있다.

profile
step by step...my devlog

0개의 댓글