본 게시글은 도서, Clean Code를 읽고 정리한 글입니다.
1. 형식을 맞추는 목적
코드 형식은 결국 의사소통의 일환이다.
그리고 의사소통은 개발자의 의무 중 하나이다.
오늘 구현한 코드는 언젠가 다른 코드로 변경되거나 유지보수되기 마련이다.
대신 형식은 변하지 않는다. 원래 코드는 사라지더라도 개발자의 스타일과 규율은 사라지지 않는다.
그리고 오늘 구현한 이 형식은 다음 코드에도 큰 영향을 끼친다.
2. 적절한 행 길이를 유지하라
신문 기사처럼 작성하라
소스파일도 신문 기사처럼, 이름은 간단하면서 설명이 가능하도록 짓자.
그리고 소스 파일의 처음 부분은 고차원 개념과 알고리즘을 설명하고, 아래로 내려갈 수록 그 의도를 서서히 드러내고, 저차원 개념을 소개한다.
개념은 빈 행으로 분리하라
package ...
import ...
public class BoldWidget extends ParentWidget {
...
public BoldWidget(){}
public String render() throws Exception {
...
}
}
위 코드처럼,
package / import / class
class 안에서도 생성자 / 메서드 등등..
개념이 달라지면 빈 행으로 분리하자.
이는 새로운 개념을 시작한다는 시각적 단서가 된다.
세로 밀집도
개념을 빈 행으로 분리했다면, 세로 밀집도는 연관성을 의미한다.
서로 밀접한 코드는 세로로 가까이 놓아야 한다는 뜻이다.
public class ReporterConfig {
private String m_className;
private List<Property> m_properties = new ArrayList<>();
public void addProperty(Property property) {
m_properties.add(property);
}
}
그냥 별다른 이해가 필요없이, 변수 2개 메서드 1개인 클래스라는 점이 쉽게 파악된다.
수직 거리
결국 서로 밀접한 개념은 세로로 가까이 둬야 한다.
아래는 각 역할과 개념에 대한 추천하는 위치 및 수직 거리이다.
변수는 사용하는 위치에 최대한 가까이 선언한다.
보통 지역 변수는 각 함수 맨 처음에 선언한다.
반면 인스턴스 변수는 클래스 맨 처음에 선언하고, 변수 간 세로로 거리를 두지 않는다.
한 함수가 다른 함수를 호출한다면 두 함수는 세로로 가깝게 배치한다.
또한 호출하는 함수를 호출되는 함수보다 먼저 배치한다.
친화도가 높은 코드일 수록 가까이 배치한다.
이 때 친화도라는게 사례가 여러가지일 수 있는데, 대표적인 예시로 종속성, 비슷한 일을 수행하는 함수 등이 있다.
public class Assert {
static public void assertTrue(String message, boolean condition) {
if(!condition)
fail(message);
}
static public void assertTrue(boolean condition) {
assertTrue(null, condition);
}
static public void assertFalse(String message, boolean condition) {
assertTrue(message, !condition);
}
static public void assertFalse(boolean condition) {
assertFalse(null, condition);
}
}
위 함수들은 개념적으로 친화한 정도가 크다. 비슷한 이름, 비슷한 기능이다. 그러므로 이러한 함수들은 가까히 배치한다.
세로 순서
일반적으로 함수를 호출하는 함수보다 호출되는 함수를 나중에 배치한다.
그렇게되면 소스 코드 모듈 상 고차원 모듈이 보통 위로 가고, 저차원 모듈이 아래로 내려가게 되어, 아까 말했던 신문 기사같은 구조도 이루어진다.
3. 가로 형식 맞추기
한 행에서 가로의 길이는 얼마가 적당할까?
많은 조사에서 프로그래머는 명백하게 짧은 행을 선호한다고 나타났다.
그리고 이 책도 그것을 추천한다. 저자는 120자 정도의 가로 제한을 추천한다.
가로 공백과 밀집도
가로로는 공백을 활용하여 밀접한 개념과 느슨한 개념을 표현한다.
private void measureLine(String line) {
lineCount++;
int lineSize = line.length();
totalChars += lineSize;
lineWidthHistogram.addLine(lineSize, lineCount);
recordWidestLine(lineSize);
}
위 코드에서는 할당 연산자 '=' 을 앞뒤로 공백을 줬다.
이유가 있는데, 공백을 통해 할당문 왼쪽 오른족의 두 가지 주요요소가 확실하게 구분된다.
반면 함수이름과 이어지는 괄호 사이에는 공백이 없는데, 함수와 인수는 명백히 연결되는 하나의 개념이기 때문이다.
그리고 이러한 가로 공백은 연산자의 우선순위를 가를 때도 의도적으로 표시한다.
들여쓰기
Scope로 이루어진 계층을 표현하기 위해서 코드에 적절한 들여쓰기가 필요하다.
클래스 내 메서드는 클래스보다 한 수준 들여쓴다.
메서드 코드는 메서드 선언보다 한 수준 들여쓴다.
블록 코드는 블록을 포함하는 코드보다 한 수준 들여쓴다.
개발자들은 코드의 왼쪽을 보면서 구조를 파악하고, 메서드 변수 클래스를 찾고, if문 while문의 여닫이를 확인한다.
들여쓰기가 잘못되면 크게 잘못 이해할 가능성이 커진다.
4. 팀 규칙
프로그래머라면 각자 선호하는 방식이 물론 있다. 하지만 팀에 들어온 이상, 팀의 규칙을 따라야 한다.
팀은 하나의 규칙에 합의해야 하고, 모든 팀원은 그 규칙을 반드시 따라야 한다.
그래야 결과물이 일관적이다.
결국 좋은 소프트웨어 시스템은 읽기 쉽다. 읽기 쉬우려면 일관적이어야 한다. 일관적이려면 규칙을 따라야 한다.
'Software Engineering > Clean Code' 카테고리의 다른 글
[Clean Code] 7. 오류 처리 (0) | 2024.02.19 |
---|---|
[Clean Code] 6. 객체와 자료 구조 (1) | 2024.01.25 |
[Clean Code] 4. 주석 (1) | 2024.01.23 |
[Clean Code] 3. 함수 (0) | 2023.11.27 |
[Clean Code] 2. 의미 있는 이름 (0) | 2023.11.22 |
개발자가 되고 싶어요.