본문 바로가기
Study/클린코드

[클린코드] 5장. 형식 맞추기

by Nahwasa 2023. 1. 2.

스터디 메인 페이지

 

- ☆ 표시가 붙은 부분은 스터디 중 나온 얘기 혹은 제 개인적인 생각이나 제가 이해한 방식을 적어놓은 것으로, 책에서 말하고자 하는 바와 다를 수 있습니다.

- 모든 이미지의 출처는 클린 코드(로버트 C. 마틴 저) 책 입니다.

 


 

5장 형식 맞추기

술 취한 뱃사람 한 무리가 짜놓은 듯 어수선해 보인다면 독자들은 프로젝트의 다른 측면도 똑같이 무성의한 태도로 처리했으리라 생각할 것이다. -> ☆ 완전 공감되는 내용이었다. 예전에 뭔 외주줘서 진행한 프로젝트를 짬처리 받은적이 있다. 그런데 저런식이다. 코드 형식을 논하기 이전에 뭔 띄어쓰기도 제대로 안되어있고, 최대한 완벽해야 할 공통코드에서 꽤 많이 사용된 isEmpty가 == "null" 이러고 있다. 돌아가는게 신기하다 ㅋㅋ. 진짜 저런식으로 짠거면 스스로 부끄럽지 않다는건데 기가 차다. 내 경우엔 해당 프로젝트의 나머지 부분은 그냥 보지도 않고 소스 받은 후 3분정도만에 삭제하고 그냥 새로 진행하겠다고 했다. 나머지 부분도 뻔하니까!

 

 

코드 형식은 의사소통의 일환이다. 코드 형식은 전문 개발자의 일차적인 의무다.

 

원래 코드는 사라질지라도 개발자의 스타일과 규율은 사라지지 않는다. -> ☆ 엄청 깔끔하게 짜여져 있는 코드를 수정하면서 굳이 엉망으로 짜는 또라이는 잘 없다.

 

 적절한 행 길이를 유지하라

  • 일반적으로 큰 파일보다 작은 파일이 이해하기 쉽다. 대부분 200줄 정도인 파일로도 커다란 시스템을 구축할 수 있다.

 

신문 기사처럼 작성하라

  • 독자는 위에서 아래로 기사를 읽는다. 
  • 신문기사처럼 소스 파일 첫 부분은 고차원 개념과 알고리즘을 설명하고 아래로 내려갈수록 의도를 세세하게 묘사한다. 마지막에는 가장 저차원 함수와 세부 내역이 나온다.
  • ☆ 나도 그렇고 주로 C로 먼저 언어를 접한 사람들이 클린코드 책에 나온 것과 반대로 아래쪽에 중요한 개념이 나온다. C의 경우 아래쪽에 있는 함수는 사용할 수 없다. 위에 선언을 따로 적어야 하는데 보통 귀찮다보니 아래쪽에서 위로 올라가면서 코드를 짜게 된다.

 

개념은 빈 행으로 분리하라

 

세로 밀집도는 연관성을 의미한다.

  • 서로 밀접한 코드 행은 세로로 가까이 놓여야 한다.
  • ☆ 그렇다고 전역 변수 - 함수 - 전역 변수 - 함수 이런식으로 밀접하다고 해당 전역 변수를 주로 사용하는 함수랑 붙여두진 말자 ㅋㅋ

 

연관성이 깊은 두 개념이 멀리 떨어져 있으면 코드를 읽는 사람이 소스 파일과 클래스를 여기저기 뒤지게 된다.

 

변수는 사용하는 위치에 최대한 가까이 선언한다.

 

인스턴스 변수 (전역 변수)는 클래스 맨 처음에 선언한다.

  • C++에서는 모든 인스턴스 변수를 클래스 마지막에 선언한다는 소위 가위 규칙을 적용한다. -> ☆ 본적 없긴하다. 일단 내가 본 다른 사람의 C++ 코드도 전부 위에 뒀긴하다.
  • 위나 아래가 중요한게 아니라, 잘 알려진 위치에 인스턴스 변수를 모은다는 사실이 중요하다.

 

호출하는 함수를 호출되는 함수보다 먼저 배치한다.

 

상수를 알아야 마땅한 함수에서 실제로 사용하는 함수로 상수를 넘겨주는 방법이 더 좋다.

  • ☆ 객체간의 관계에서도 동일하다. 의존성 주입(DI)에 해당한다. defaultPage가 뭔지 알기 위해 코드를 뒤져봐야 하는 것 자체가 캡슐화가 무너진 것이다.

 

개념적 유사성이 높을수록 코드를 가까이 배치한다.

  • e.g. assertTrue(), assertFalse() 이런 것들은 비슷한 위치에 코드를 둔다.

 

함수 호출 종속성은 아래 방향으로 유지한다.

 

120자 정도로 행 길이를 제한한다.

  • ☆ 인텔리제이의 경우 코드 쓰는 부분에 세로줄이 그어져 있는데 그게 이 용도이다. 대략 110자 정도가 기본으로 세팅되어 있다. 넘었다고 오류가 나는건 아니지만 주의하라는 의미이다.

 

 

연산자 우선순위를 강조하기 위해서도 공백을 사용한다.

  • ☆ 이건 엄청 좋은 팁인 것 같다. 백준 9206을 풀었던 코드에 수식이 많았어서 한번 시도해봤다. 결론적으로 저 아래쪽의 ans+= 부분처럼 너무 복잡한 경우엔 크게 의미가 없었지만, 중간에 f() 함수의 경우엔 확실히 보기 편해진다.
class Vase {
    private double a, b, h, interval;
    private int numOfInterval;

    public Vase(StringTokenizer st) {
        this.a = Double.parseDouble(st.nextToken());
        this.b = Double.parseDouble(st.nextToken());
        this.h = Double.parseDouble(st.nextToken());
        this.numOfInterval = (int) Math.ceil(h/Tags.X_DIVIDE_GAP);
        this.interval = h/numOfInterval;
    }

    private double f(double x) {
        return a*Math.exp(-(x*x))+b*Math.sqrt(x);
        return a*Math.exp(-x*x) + b*Math.sqrt(x);
    }

    private double g(double x) {
        double fx = f(x);
        return fx*fx*Math.PI;
    }

    public double getVolume() {
        double ans = 0.0d;
        for (int i = 0; i < numOfInterval; i++) {
            double a = interval*i;
            double b = interval*(i+1);
            ans += interval/6*(g(a)+4*g((a+b)/2)+g(b));
            ans += interval/6*(g(a) + 4*g((a+b)/2) + g(b));
        }
        return ans;
    }
}

 

가로 정렬은 별로 유용하지 못하다.

 

프로그래머는 들여쓰기 체계에 크게 의존한다. 들여쓰기가 없다면 인간이 코드를 읽기란 거의 불가능하다.

  • 들여쓰기한 파일은 구조가 한눈에 들어온다.

 

가짜 범위

  • 빈 while문이나 for문의 경우 아래와 같이 새 행에다가 세미콜론을 넣어준다.
while (dis.read(buf, 0, readBufferSize) != -1)
;
  • ☆ 개인적으로는 아래와 같은 방식을 더 선호한다. 내 경우엔 책의 방식보단 아직은 내 방식이 더 눈에 잘 띄고 명확하다고 생각되서 바꾸진 않을 것 같다.
while (dis.read(buf, 0, readBufferSize) != -1) {
	// do nothing
}

 

팀 규칙

  • 팀은 한 가지 규칙에 합의해야 한다. 그리고 모든 팀원은 그 규칙에 따라야 한다.

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

[클린코드] 7장. 오류 처리  (0) 2023.01.02
[클린코드] 6장. 객체와 자료 구조  (0) 2023.01.02
[클린코드] 4장. 주석  (0) 2022.12.21
[클린코드] 3장. 함수  (0) 2022.12.20
[클린코드] 2장. 의미 있는 이름  (0) 2022.12.14

댓글