형식은 읽는 순서를 만든다

코드 형식은 겉모습의 문제가 아니다. 같은 로직이라도 줄바꿈, 빈 줄, 들여쓰기, 배치 방식에 따라 읽는 속도와 이해도가 달라진다. 코드는 작성되는 시간보다 읽히는 시간이 훨씬 길기 때문에, 형식은 유지보수성을 결정하는 중요한 요소가 된다.

잘 정리된 파일은 신문 기사처럼 위에서 아래로 자연스럽게 읽힌다. 파일 이름과 첫 부분에서 큰 의도를 파악하고, 아래로 내려갈수록 세부 구현을 확인할 수 있어야 한다. 너무 긴 파일은 한 번에 담아야 할 맥락이 많아지므로 가능하면 작게 유지하는 편이 좋다.

줄과 빈 줄

긴 줄은 읽는 사람에게 많은 정보를 한 번에 요구한다. 적절히 줄을 나누면 호출 흐름과 예외 처리 지점이 더 잘 보인다.

String userDetails = userRepository.findByName("John Doe")
        .orElseThrow(() -> new UserNotFoundException("사용자를 찾을 수 없습니다."))
        .getDetails();

빈 줄은 서로 다른 개념을 구분하는 역할을 한다. 관련 있는 코드는 가까이 두고, 다른 목적의 코드는 빈 줄로 나누면 시선이 덜 흔들린다.

public class UserManagement {
    private UserRepository userRepository;
 
    public UserManagement(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
 
    public void addUser(User user) {
        validateUser(user);
        userRepository.save(user);
    }
 
    private void validateUser(User user) {
        // 검증 로직
    }
}

가까운 개념은 가까이 둔다

서로 관련된 코드는 물리적으로도 가까워야 한다. 변수는 사용되는 위치 근처에 두고, 서로 호출하는 함수는 멀리 떨어뜨리지 않는 편이 좋다. 상위 개념은 위에, 세부 구현은 아래에 두면 코드를 읽는 흐름이 자연스러워진다.

public class Authentication {
    public User login(String username, String password) {
        // 로그인 로직
    }
 
    private boolean isValidCredential(String username, String password) {
        // 검증 로직
    }
}

가로 형식도 같은 원칙을 따른다. 공백은 관계를 드러내기 위해 사용해야지, 의미 없는 정렬을 위해 과하게 사용할 필요는 없다. 들여쓰기는 코드의 구조를 보여주는 가장 기본적인 장치이므로 팀 안에서 일관되게 유지해야 한다.

팀의 규칙을 따른다

형식은 개인 취향으로만 두면 파일마다 다른 리듬을 만든다. 팀이 정한 규칙이 있다면 그 규칙을 따르는 편이 좋다. 중요한 것은 어떤 스타일이 절대적으로 옳은지가 아니라, 한 프로젝트 안에서 예측 가능한 모양을 유지하는 것이다.

포매터를 사용하는 것도 좋은 방법이다. 기계가 처리할 수 있는 논쟁은 기계에게 맡기고, 개발자는 이름과 구조처럼 더 중요한 문제에 집중할 수 있다. 일관된 형식은 코드 리뷰의 잡음을 줄이고 코드의 내용에 더 집중하게 만든다.

결국 형식 맞추기는 코드를 예쁘게 보이게 하는 일이 아니라, 다음 사람이 덜 헤매도록 길을 정리하는 일이다.

다음장으로 6장