Clean Code 2장

손우진·2020년 11월 30일
0

독서

목록 보기
2/2

CLEAN CODE 2장

2장에서는 이름 짓기, 네이밍에 관한 내용들이 있었다.
당연한 부분이라 하면 당연한 부분이겠지만, 일상적으로 사용하면서 놓치는 부분도 많았다.

이름 짓기

이름을 지을 때에 의도를 분명히 밝히는 이름으로 지어야 한다.
의도를 분명히 밝히기 위해서는 여러 가지를 지켜서 의도를 밝혀야 한다.

변수 이름을 줄여 쓰지 않기

여러 곳에서 본 말이었다. 제일 생각나는 부분은 얼마 전 temp에 대한 이야기였다.
친구의 첫 줄 프로젝트에서는 글을 분석해서 온도로 측정하는데, 팀원이 이를 temperature이라는 변수가 아닌 temp로 작성하여 생기는 문제를 보았다.
temp라고 작성하면 처음 보기엔 '임시' 변수라고 착각하기 쉽다.
사실, 임시로 작성하는 변수 또한 temp라고 작성해서는 안된다.

상수를 하드코딩하지 않기

흔히들 for문을 쓸 때 반복 횟수가 고정되어 있다면 이렇게 사용한다.

for(int i=0; i<4; i++){
//내용
}

이렇게 쓰면 차후에 이 코드를 볼 때, 4가 무엇을 의미하는지, 심지어 i도 뭔지 모른다.
우선 첫 번째로, 꼭 반복 횟수를 변수로 가져야 할 필요가 없다면 이렇게 반복문을 쓰자.

public List<int[]> getThem(){

    List<int[]> list1 = new ArrayList<int[]>();
    for(int[] x : theList)
    	if(x[0]==4)
    		list.add(x);
    return list1;
}

이 코드도 이게 뭐하는 코드인지는 사실 알 수 없다.
이 코드가 지뢰 찾기 게임에 사용되는 코드로 가정하고 바꿔보자.

public List<int[]> getFlaggedCells(){

    List<int[]> flaggedCells = new ArrayList<int[]>();
    for(int[] cell : gameBoard)
    	if(cell[STATUS_VALUE]==FLAGGED)
    		flaggedCells.add(cell);
    return flaggedCells;
}

이러면 이제 이게 뭘 하는 코드인지 이름을 잘 지어서 구분할 수 있게 되었다.
0번 index는 STATUS_VALUE 즉 해당 cell의 상태를 의미하는 것이었고,
4는 깃발 상태라는 것이었다.
이 위에 있는 걸로는 아마도

const int STATUS_VALUE = 0;
const int FLAGGED = 4;

이렇게 있을 것이다.

배열도 간단한 클래스로 사용하기(일급 컬렉션)

위의 코드도 바꿀 점이 한 가지 더 있었다.
굳이 list에 int 배열을 넣지 않고, 이 int 배열 또한 뭘 의미하는지 알려주는 것이다.
int 배열을 멤버변수로 가진 클래스를 하나 만들어주면, 이 조금 더 의미가 명확해진다.

public List<Cell> getFlaggedCells(){
    List<Cell> flaggedCells = new ArrayList<int[]>();
    for(Cell cell : gameBoard)
    	if(cell.isFlagged)
    		flaggedCells.add(cell);
    return flaggedCells;
}

이러면 사실 STATUS_VALUE 따위의 상수도 필요없이 조금 더 깔끔하다고 느낄 수 있을 것이다.

네이밍을 연속된 숫자로 쓰지 않기

이러한 a1, a2와 같은 네이밍을 쓰는 사람이 많지는 않다.
다만, 나의 경험으로는 특히 override 할 때, 특히 compare 메소드에서 많이 썻다..

class MyComparator implements Comparator<Point> {
  @Override
  public int compare(Point p1, Point p2) {
    if (p1.x > p2.x) {
      return 1; // x에 대해서는 오름차순
    }
    else if (p1.x == p2.x) {
      if (p1.y < p2.y) { // y에 대해서는 내림차순
        return 1;
      }
    }
    return -1;
  }
}

이러한 코드에서 p1과 p2가 주석이 없고 Comparator 인터페이스에 대한 기반 지식이 없다면, 이게 뭐가 오름차순이고 내림차순인지 구별하기 어려울 것이다.
사소한 함수 인자에서도 의미 있는 이름을 지어주자.

변수 이름에 불용어를 사용하지 않기

되게 흔하게 사용하는 경우라고 생각했다.
흔히 Person 클래스가 있고, 이러한 객체의 정보를 전달하기 위해 PersonInfo, PersonData라는 클래스를 만드는 경우가 많다.
사실 그러한 정보라는 건 Person 클래스에 다 담겨있어야 한다. 구분되지 못하는 클래스라는 것이다.
당연히 a, the와 같은 접두어도 의미 없이 사용하지 않아야 한다. 한 눈에 이 클래스가, 이 함수가, 이 변수가 무엇을 하는 것인지 알아보는데 방해가 되는 것들이다.

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

generate date, year, month, day, hour, minute, second 라는 정보가 있는 클래스를 웃기게 함축해버려서 genymdhms 클래스라는 이름을 붙였다 하자.
다른 개발자에게 이 클래스를 이야기할 때 설명 없이는 이 클래스를 부를 수 조차 없다.
커뮤니케이션을 할 수 있는 이름을 사용해야 한다.
코드는 개발자간의 대화이기 때문이다.

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

i 라는 변수를 사용하면, i를 찾기 위해 ctrl+f를 해서 찾다가 화가 날 것이다.
변수 이름의 길이는 변수가 사용되는 범위에 맞게 비례해서 길어져야 한다.
해당 변수가 어디서 사용되는지 찾을 때 도움이 될 것이다.
특히 한 문자로 이루어진 이름은 함수 하나, 그 중에서도 블록 하나 이상을 넘어서지 않는게 좋다.

변수 이름에 인코딩을 피한다.

변수 이름엔 접두어를 피하는 것이 좋다. 왠만하면 접두어를 사용하지 않아도 될 만큼 함수의 크기, 클래스의 크기는 작아야 한다.
인터페이스와 구현 클래스의 이름에는 인코딩이 필요한 경우가 있을 수 있다.
그럴 때에는 인터페이스 클래스보다는, 구현 클래스의 이름을 바꿔주는 쪽으로 하는게 올바르다.
당장 자바의 Queue 클래스도 인터페이스이지만, 이름에서는 이게 인터페이스인지 뭔지 알 수 없다. 사용하는 입장에서는 그게 맞다.

이름의 품사

함수의 이름은 동사나 동사구로 짓는다. 함수는 어떤 행위이기 때문이다.
클래스의 이름은 명사나 명사구로 짓는다. 클래스는 어떠한 객체이다.
접근자, 변경자, 조건자의 경우 javabean 표준에 따라 get, set, is를 붙인다.
생성자를 중복정의할 때에는 정적 팩토리 메소드를 사용한다.
이 때 메소드는 인수를 설명하는 이름을 사용한다.

이름의 내용

기발한 이름을 피하라. - 구어체나 속어를 이름으로 사용하지 마라
한 개념에 한 단어를 사용하라. - 같은 개념인데 여러 가지로 섞어 쓰지 마라
ex) driver, controller, manager

이름의 개념

해법 영역에서 가져온 이름을 사용하라.
이름을 전산 용어, 알고리즘 이름, 패턴 이름 등 적절한 '프로그래머 용어' 를 사용하라.
코드는 개발자간의 대화이기 때문이다.
적절한 프로그래머 용어가 없다면 문제 영역, 즉 해당 프로그램이 사용될 도메인에서 가져온 용어를 사용해라.

이름의 맥락

의미 있는 맥락을 추가하라.
클래스 안에 담아서 맥락을 추가할 수 없다면 부득이하게라도 접두어를 사용하라.
ex) addrFirstName, addrState 등
불필요한 맥락을 없애라.
ex) address란 변수를 고급 휘발류 충전소(Gas Station Deluxe)라는 어플리케이션 안에서 사용한다고, 그 주소 정보를 가지는 변수를 GSDAddress로 할 필요는 없다. 주소는 그 자체로 주소이기 때문이다.
변수의 이름을 명확하게 하기 위해 맥락을 추가하는 것은 좋지만, 의미 없는 맥락을 추가해서는 안된다.

생각

클린 코드에 대한 관심을 가지기 시작한 이유는, 이전에 했던 프로젝트들의 완성도를 높이기 위해 git 저장소를 열어본 순간 알아보기가 너무 힘들어서였다.
뛰어난 사람들의 생각과 그들의 방법을 접목하면 할수록 내 코드는 누구나 읽기 좋아지지 않을까?

profile
Backend Developer @비바리퍼블리카

0개의 댓글