해당 글은 챕터를 읽고 느끼는 바에 대하여 쓴 글입니다.
주관적인 해석이 들어갈 수 있으니, 참고 부탁드려요.
프로그래머라면 모든 코드를 형식에 맞춰 깔끔하게 코드를 짜야한다.
당신이 만약 팀 안에서 일을 하고 있다면, 팀에서 합의를 통해 규칙을 정하고 모두가 그 규칙을 따라야 한다.
형식을 맞추는 목적
코드 형식은 너무나도 중요하다.
왜냐하면 코드 형식은 의사소통의 일환이기 때문이다.
의사소통은 개발자들에게 있어서 일차적인 의무이다.
그렇다면 원활한 소통을 위해 필요한 코드 형식은 무엇일까?
1. 적절한 행 길이를 유지하라.
적절한 행 길이는 개발자들이 코드를 읽는 데에 도움을 줄 수 있다.
JUnit, FitNesse, testNG 같은 대형 프로젝트를 살펴볼 때, 최대 Line이 500 Line이 넘어가는 일이 없으며,
대부분 200 Line 미만에서 코드가 작성되고 있다.
이 뜻은 한 클래스 안에 많은 의미를 담고 있지 않더라도 충분히 프로젝트를 만들어 낼 수 있다는 뜻이다.
일반적으로 큰 파일보다 작은 파일이 이해하기 쉽다.
신문 기사처럼 작성하라.
신문을 읽을 때 독자는 위에서 아래로 기사를 읽는다.
표제, 본문, 세부사항 등등 순으로 나열되며 글이 전개된다.
소스파일도 마찬가지이다. 이름은 간단하면서도 설명이 가능하게 짓는다.
소스 파일 첫 부분은 고차원 개념과 알고리즘을 설명한다.
또한 기사는 대다수 매우 짧다. 한 면을 채우는 기사는 거의 없다.
코드도 장황하게 길 필요가 없다.
개념은 빈 행으로 분리하라.
생각 사이는 빈 행을 넣어 분리해야 마땅하다.
일련의 행 묶음 완결된 생각 하나를 표현하기 때문이다.
다음 예시로 빈행이 왜 중요한지 확실하게 알 수 있다.
빈행으로 분리했을 때
package onboarding;
import java.util.List;
import java.util.stream.Stream;
class Problem1 {
}
빈행으로 분리하지 않았을 때
package onboarding;
import java.util.List;
import java.util.stream.Stream;
class Problem1 {
}
눈의 초점을 흐리게 하고 코드를 바라보면 효과는 더욱 분명하게 드러난다.
세로 밀집도
서로 밀접한 코드 행은 세로로 가까이 놓여야 한다.
public static int getMaxNumber(List<Integer> arrayList) {
//변수
int result = 0;
int resultByAdd = 0;
int resultByProduct = 0;
//로직
for (Integer pageNumber : arrayList) {
resultByAdd = Stream.of(String.valueOf(pageNumber).split(""))
.mapToInt(Integer::parseInt).reduce(0, Integer::sum);
resultByProduct = Stream.of(String.valueOf(pageNumber).split(""))
.mapToInt(Integer::parseInt).reduce(1, (a, b) -> a * b);
}
//결과값
return Integer.max(resultByAdd, resultByProduct);
}
위 코드와 같이 변수가 3개 for문, return 으로 나누어진다는 것을 알 수 있다.
수직 거리
서로 밀접한 개념은 세로로 가까이 둬야 한다.
(1) 변수
변수는 사용하는 위치에 최대한 가까이 선언한다.
또한 지역변수는 각 함수 맨 처음에 선언한다.
(2) 인스턴스 변수
반면 인스턴스 변수는 클래스 맨 처음에 선언한다.
변수 간에 세로로 거리를 두지 않는다.
잘 알려진 위치에 인스턴스를 모은다는 사실이 중요하다.
(3) 개념 유사성
친화도가 높을수록 코드를 가까이 배치한다.
친화도가 높은 요인은 다음과 같다.
- 다른 함수를 호출해 생기는 직접적인 종속성
- 변수와 그 변수를 사용하는 혐수
- 비슷한 동작을 수행하는 일군의 함수
여기서 비슷한 동작을 수행하는 일군의 함수라 함은 다음 코드와 같다.
//우리가 흔히 쓰는 테스트코드 함수 중 하나
//참조 org.junit.jupiter.api.Assertions
public static void assertTrue(boolean condition) {
AssertTrue.assertTrue(condition);
}
public static void assertTrue(boolean condition, Supplier<String> messageSupplier) {
AssertTrue.assertTrue(condition, messageSupplier);
}
public static void assertTrue(BooleanSupplier booleanSupplier) {
AssertTrue.assertTrue(booleanSupplier);
}
public static void assertTrue(BooleanSupplier booleanSupplier, String message) {
AssertTrue.assertTrue(booleanSupplier, message);
}
위와 같이 명명법이 똑같고 기본 기능이 유사하고 간단한 코드들이다.
서로가 서로를 호출하는 관계는 부차적인 요인이며, 종석적인 관계가 없더라도 가까이 배치할 함수들이다.
2. 가로 형식 맞추기
가로길이는 그럼 얼마가 적당할까?
여기서도 프로젝트를 살펴보았을 때, 보통 45자 근처가 매우 많이 작성되었다는 것을 알 수 있다.
프로그래머는 명백하게 짧은 행을 선호한다.
가로 공백과 밀집도
가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한다.
함수 이름과 이어지는 괄호 사이에는 공백을 넣지 않은 경우
public static <V> V fail(String message, Throwable cause) {
AssertionUtils.fail(message, cause);
return null;
}
함수 이름과 이어지는 괄호 사이에는 공백을 넣지 않은 경우
public static double root(int a, int b, int c){
double determinant = determinant(a, b, c);
return (-b - Math.sqrt(determinanat)) / (2*a);
}
위와 같이 공백에 대하여 분명하게 규칙을 정할 경우 개발자 입장에서는 읽기가 매우 편하다.
가로 정렬
많은 변수들이 선언되곤 할 때(ex. Constant를 집합시켜 놓은 상수라던가.. 등등)
보통 가로 정렬들을 많이 했으나, 오히려 엉뚱한 부분을 강조해 의도가 가려질 수 있는 위험이 있다.
다음 코드로 보자.
public class Constants{
public static final String DATE_FORMAT_YMDHMS = "yyyyMMddHHmmss";
public static final String DATE_FORMAT_YMD = "yyyyMMdd";
public static final String PROFILES_LOCAL = "local";
public static final String PROFILES_PROD = "prod";
public static final String CMM_YN_Y = "Y";
public static final String CMM_YN_N = "N";
public static final String DELIMITER_BAR = "|";
public FitNesseExpediter(Socket s,
fitNesseContext context) throw Exception{
}
...
위와 같은 코드를 봤을 때, 매우 이질적인 것을 볼 수 있다.
따라서 가로 정렬은 되도록이면 추천하지 않는다.
들여쓰기(indent)
소스 파일은 윤곽도와 계층이 비슷하다.
범위로 이뤄진 계층을 표현하기 위해 우리는 코드를 들여 쓴다.
들여 쓰는 정도는 계층에서 코드가 자리 잡은 수준에 비례한다.
(요즘에 나오는 개발 Tool은 자동적으로 들여 쓰기가 되도록 매우 잘 설계되어 있다.)
들여쓰기가 있는 파일은 구조가 한눈에 들어온다.
3. 팀 규칙
팀은 한 가지 규칙에 합의해야 한다.
그리고 모든 팀원은 그 규칙을 따라야 한다.
그래야 소프트웨어가 일관적인 스타일을 보일 수 있다.
좋은 소프트웨어 시스템은 읽기 쉬운 문서로 이뤄진다는 사실에 입각한다.
'책 리뷰 > Clean Code' 카테고리의 다른 글
2장. 의미 있는 이름 (0) | 2023.02.15 |
---|