코드 가독성의 딜레마: 쪼갤 것인가, 흘려보낼 것인가? - Part 1. 추상화 수준 일치

반응형

Part 1. 읽기 좋은 코드를 만드는 비결: 추상화 수준 일치시키기

우리는 "돌아가는 코드"를 짜는 것을 넘어 "읽기 좋은 코드"를 짜기 위해 끊임없이 고민합니다.

코드를 작성하는 것보다 기존 코드를 읽고 이해하는데 더 많은 시간을 쏟기 때문입니다.

그래서 코드의 가독성을 높이는 '추상화 수준(Abstraction Level) 분리'에 대해 이야기해보려 합니다.

 

이 글은 구글 테스팅 블로그에 나온 내용을 기반으로 합니다.

https://testing.googleblog.com/2023/09/use-abstraction-to-improve-function.html

 

Use Abstraction to Improve Function Readability

This is another post in our Code Health series. A version of this post originally appeared in Google bathrooms worldwide as a Google Testin...

testing.googleblog.com

 

추상화 수준 일치시키기

추상화 수준 분리

코드가 길면 읽기 어렵습니다.

하지만 단순히 코드가 '길어서' 어려운 것은 아닙니다.

 

진짜 문제는 '무엇(What)'을 하는지와 '어떻게(How)' 하는지가 한곳에 뒤섞여 있기 때문입니다.

하나의 함수 안에 비즈니스 로직(고수준)과 구체적인 구현 상세(저수준)가 혼재되어 있으면,

코드를 읽는 사람은 계속해서 맥락을 바꿔야 합니다.

이를 '추상화 수준의 혼합(Mixing levels of abstraction)'이라고 합니다.

 

이제 두개의 코드를 비교해 보겠습니다.

추상화 수준을 맞추기 전

아래는 주문 처리 코드입니다.

public void processOrder(Order order) {
    // 1. 재고 확인 (DB 연결 같은 저수준 로직)
    if (order.getItems().size() == 0) {
        throw new RuntimeException("주문 상품이 없습니다.");
    }
    Connection conn = dbFactory.getConnection();
    PreparedStatement stmt = conn.prepareStatement("SELECT stock FROM items WHERE id = ?");
    // ... DB 쿼리 실행 및 결과 확인 코드 ...
    
    // 2. 결제 처리 (외부 API 호출 상세 구현)
    String payload = "{ 'amount': " + order.getTotalPrice() + ", 'card': ... }";
    HttpClient client = new HttpClient();
    Response response = client.post("https://payment-gateway.com/api", payload);
    if (response.getCode() != 200) {
        // ... 에러 핸들링 ...
    }

    // 3. 이메일 발송 (SMTP 프로토콜 상세)
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    // ... 이메일 세션 생성 및 메시지 작성 ...
    Transport.send(msg);
}

processOrder 함수는 '주문을 처리한다' 라는 높은 수준의 개념을 다룹니다.

하지만 내부에는 DB 연결, HTTP 통신같은 상세 구현(저수준)이 들어가 있습니다.

즉, 전체적인 흐름(고수준)과 그 흐름의 모든 상세 내용(저수준) 가 하나의 함수에 들어가 있습니다.

이러한 것을 추상화 수준의 혼합(mixes together several levels of abstraction) 이라고 합니다.

 

이러한 코드는 전체적인 흐름을 파악하려 해도, 세부적인 기술 구현 내용이 시야를 가려버려 이해하기 어렵게 만듭니다.

추상화 수준을 맞춘 후

이제 이 코드의 추상화 레벨을 일치시켜보겠습니다.

상세 구현을 별도의 함수로 만들어서 숨기겠습니다.

아래는 수정 후의 코드입니다.

public void processOrder(Order order) {
    validateOrder(order);      // 고수준
    checkInventory(order);     // 고수준
    processPayment(order);     // 고수준
    sendConfirmationEmail(order); // 고수준
}

// 각 함수는 자신의 추상화 수준에 맞는 '상세'를 다룹니다.
private void checkInventory(Order order) {
    // DB 연결 및 재고 확인 로직은 여기에 숨김
}

private void processPayment(Order order) {
    // 결제 API 호출 로직은 여기에 숨김
}

 

코드의 추상화 레벨을 일치시키고 나니 코드를 읽기가 한결 수월해졌습니다.

processOrder 가 어떤 절차로 수행되는지가 한눈에 들어옵니다.

상세 내용이 궁금하다면 그때마다 그 함수로 들어가서 확인하면 됩니다.

 

예전에 뉴스신문을 읽는 방식과 매우 유사합니다.

뉴스신문을 읽을 때 전체적인 헤드라인을 먼저 훑어봅니다.

그렇게 하루동안 무슨 일이 있었는지 쉽게 파악하고,

궁금한 부분만 세부 내용(본문)을 더 읽어봅니다.

 

잘 작성된 코드는 위에서 아래(Top-down)로 물 흐르듯이 읽혀야 합니다.

상위 함수(고수준 담당)는 헤드라인 역할이고, 저수준을 구현한 함수는 본문 역할입니다.

 

 

평소에 읽기 힘들었던 함수가 있다면, 추상화 수준을 맞춰보는 것도 좋은 방법이 될 수 있습니다.

 

2025.12.13 - [잡다한 지식] - 코드 가독성의 딜레마: 쪼갤 것인가, 흘려보낼 것인가? - Part 2. 선형 코드

2025.12.13 - [잡다한 지식] - 코드 가독성의 딜레마: 쪼갤 것인가, 흘려보낼 것인가? - Part 3. 추상화와 선형코드 사이에서 균형 잡기

반응형