Search
Duplicate

5장 형식 맞추기

개인적 감상평

정보를 받아들이는 속도를 올리기 위해서는 보기 좋아야 한다. 보기좋은 떡이 먹기도 좋다고 하지 않은가?
서버랙 케이블의 정리전과 정리 후 모습이다. 형식이 맞춰지지 않은 코드는 위 이미지의 좌측과 같다.
새로운 코드(선)을 추가하려고해도 어디에 꼽아서 그 선을 어디에 연결해야 하는지 찾는게 너무나도 어렵다. 또한 이미 어질러져 있는 상황에서 내가 추가한 코드를 정리하는게 의미가있을까? 나역시 새로운 추가 작업코드들 역시 어질러져있게되고 한층 깊은 혼돈이 펼쳐지게 된다.
반면, 우측 이미지는 어떤가? 한눈에도 어디에 연결된 선이 어디로 연결되는지 알아보기 쉽다. 새로운 연결을하거나 선을 변경하거나 하는 것 역시 묶여있는 케이블타이만 풀어서 작업후 다시 그 부분만 케이블타이로 묶어서 정리해주면 된다. 이처럼 형식을 맞추고 정리를 하는것이 중요하다.
5 장은 코드를 어떻게 형식을 맞추고 정리를 하는지에 대해 말한다.

1. 형식을 맞추는 목적

내가 오늘 구현한 기능은 다음 기능에서 바뀔 확률이 몹시 높다.
그런데 기존에 작성한 코드의 가독성이 너무나도 떨어져서 읽기조차 힘들다면?
동일한 작업을하더라도 1시간이 걸릴지 1일이 걸릴지는 가독성이 큰 영향을 미친다.
하지만 처음에 구현 스타일과 가독성 수준의 형식을 맞춰놓으면 적어도 1시간 걸릴작업을 1일까지 키우지는 않을 것이다.

2. 적절한 행 길이를 유지하라.

위 그림은 대형 프로젝트 7가지의 각 프로젝트 별 최대 파일 길이와 최소 파일길이를 나타냅니다.
그림 5.1이 우리에게 말하는 것은 무엇일까? 바로 500줄도 넘지 않고 200줄 정도의 파일로도 대규모 시스템을 구축할 수 있다는 점이다. 일반적으로 1000줄 짜리 코드보단 200줄 짜리 코드가 이해하기 더 쉽다.
신문 기사처럼 작성하라.
개념은 빈 행으로 분리하라.

세로 밀집도

줄 바꿈이 개념을 분리하다면 세로 밀집도는 연관성을 의미한다.
즉, 서로 밀접한 코드 행을 세로로 가까히 놓여야 한다는 의미다.
//worst case public class A{ /** * A클래스의 나이 */ private int age; /** * A클래스의 이름 */ private String name; public void setAge(int age){ this.age = age; } }
Java
복사
//good case public class A{ private int age; private String name; public void setAge(int age){ this.age = age; } }
Java
복사

수직 거리

서로 밀접한 개념은 세로로 가까이 둬서 코드를 트레이싱할 때 함수간을 오가며 소스 코드를 위 아래로 중구난방 돌아다니는 일은 없어야 한다.
변수 선언
인스턴스 변수
종속 함수
개념적 유사성

세로 순서

위에서 아래로 자연스럽게 읽혀지도록 작성한다.
가장 중요한 개념을 가장 먼저 표현한다.
세세한 사항일수록 나중에 표현한다.

2. 가로 형식 맞추기

세로 형식과 마찮가지로 프로젝트 7개의 행 길이 분포를 조사한 결과 60자 이하까지가 70%정도이고 그 이후 80자 이후부터는 행수가 급격히 감소한다.
대형 프로젝트에서도 최대한 짧은 행을사용하여 구성을 하고 있다.
책에서는 120자 정도로 행 길이를 제한하는 것을 권장한다.
실제로 IntelliJ에서도 세로로 vertical line이 그려져있는데 이게 딱 120라인까지고 이를 벗어나면 warning이 뜬다.

가로 공백과 밀집도

공백을 넣으면 나눠진 요소가 분명해지기에 별도로 구분해야하거나 강조해야하는 부분에 공백을 넣도록 하자.
//할당 연산자 int lineSize = line.length(); totalChars += lineSize; //함수의 인수 public static double root1(double a, double b, double c){ double determinant = determinant(a, b, c); } //사칙연산 우선순위 공백 public static double determinant(double a, double b, double c){ return b*b - 4*a*c; }
Java
복사
⇒ 사칙연산에서 곱셈은 우선순위가 더 높기때문에 공백이 없고 덧셈과 뺄셈은 우선순위가 더 낮기 때문에 공백을 줘서 어느것이 먼저 연산되는지를 알기 쉽게 된다.

가로 정렬

선언문과 할당문을 별도로 정렬하지말자.
변수명과 할당내용을 따로 읽게되며 연관짓는데 더 시간이 걸리게 된다.

3. 들여쓰기

: 소스 파일에는 파일 전체, 파일 내 개별 클래스, 클래스 내 각 메서드, 블록 내 블록 등 각 계층별로 적용되는 정보가 있습니다. 이 각계층은 각자의 스코프로 이뤄져있고 이 계층을 표현하기위해 들여쓰기를 한다.
들여쓰는 수준이 소스파일내에서 해당 코드의 계층의 깊이를 보여준다.
클래스 > 메소드 > 블록코드 순으로 들여쓰기 계층의 깊이를 더해가며 블록 코드내의 블록코드가 생성되면 이때 역시 계층의 깊이는 깊어진다. 이는 독자(개발자)가 소스를 읽을때 로직의 범위를 알기 쉽게 해주며 특정 블럭을 볼 때 다른 블럭까지 연관지어 보지 않도록 한다.
//worst case 들여쓰기를 하지 않은 코드 public class FitNesseServer implements SocketServer { private FitNesseContext context; public FitNesseServer(FitNesseContext context) { this.context context; } public void serve(Socket s) { serve(s, 10000); } public void serve(Socket s, long requestTimeout) { try { FitNesseExpediter sender = new FitNesseExpediter(s, context); sender.setRequestParsingTimeLimit(requestTimeout); sender.start(); } catch(Exception e) { e.printStackTrace(); } } } //good case 들여쓰기를 한 코드 public class FitNesseServer implements SocketServer { private FitNesseContext context ; public FitNesseServer(FitNesseContext context) { this.context = context; } public void serve(Socket s) { serve(s, 10000); } public void serve(Socket s, long requestTimeout) { try { FitNesseExpediter sender = new FitNesseExpediter(s, context); sender.setRequestParsingTimeLimit(requestTimeout); sender. start(); } catch (Exception e) { e.printStackTrace(); } } }
Java
복사

가짜 범위

때로 빈 while문이나 for문을 접하는데, 이런 경우 키워드 괄호 끝에 세미콜론(;)을 개행해서 넣어주도록 하자.
while (dis.read(buf, 0, readBufferSize) != -1) ;
Java
복사

4. 팀 규칙

팀은 한 가지 규칙에 합의하고 팀원든 그 규칙을 따라야 소프트웨어가 일관적인 스타일을 보입니다.