코드 가독성을 높이는 시각적 구조 설계

눈에 잘 들어오는 코드는 이해하기 쉬우며, 이는 장기적으로 유지보수성과 협업 효율성을 높이는 핵심 요소다. 단순한 기능 구현을 넘어서, 코드의 시각적 배치와 일관성은 개발자의 인지 부담을 줄이고 오류를 조기에 발견할 수 있도록 도와준다.

줄 바꿈 최적화로 가독성 향상

아래 예제는 초기에 각 파라미터에 주석을 달아 설명하려 한 의도는 좋지만, 세로 공간을 과도하게 차지하며 중복된 주석이 반복되어 시각적 노이즈가 된다.

public class PerformanceTester {
    public static final TcpConnectionSimulator wifi =
        new TcpConnectionSimulator(
            500,   /* Kbps */
            80,    /* millisecs latency */
            200,   /* jitter */
            1      /* packet loss % */);

    public static final TcpConnectionSimulator t3_fiber =
        new TcpConnectionSimulator(
            45000, /* Kbps */
            10,    /* millisecs latency */
            0,     /* jitter */
            0      /* packet loss % */);
}

반면, 전체 파라미터 의미를 상단 주석으로 정리하고, 생성자 호출을 한 줄에 기술하면 훨씬 간결해진다.

public class PerformanceTester {
    // Connection: (bandwidth_Kbps, latency_ms, jitter_ms, loss_percent)
    public static final TcpConnectionSimulator wifi =
        new TcpConnectionSimulator(500, 80, 200, 1);
    public static final TcpConnectionSimulator t3_fiber =
        new TcpConnectionSimulator(45000, 10, 0, 0);
}

불규칙한 로직은 함수로 추상화

다음과 같은 반복적인 테스트 코드는 구조가 고르지 못하고 중복이 많다.

assert(ExpandFullName(db_conn, "Doug Adams", &err) == "Mr. Douglas Adams");
assert(err == "");
assert(ExpandFullName(db_conn, " Jake Brown ", &err) == "Mr. Jake Brown III");
assert(err == "");

공통 패턴을 별도 함수로 분리하면, 테스트 케이스 자체가 명세처럼 읽힌다.

void VerifyNameExpansion(string input, string expectedName, string expectedError) {
    string error;
    string result = ExpandFullName(database_connection, input, &error);
    assert(result == expectedName);
    assert(error == expectedError);
}

VerifyNameExpansion("Doug Adams", "Mr. Douglas Adams", "");
VerifyNameExpansion(" Jake Brown ", "Mr. Jake Brown III", "");

이 방식은 코드 중복 제거뿐 아니라 새로운 테스트 추가도 용이하게 만든다.

열 정렬을 통한 정보 그룹화

함수 호출 내 인자가 여러 줄에 걸쳐 나열될 경우, 열 기준으로 정렬하면 값의 대응 관계를 직관적으로 파악할 수 있다.

VerifyNameExpansion("Doug Adams"  , "Mr. Douglas Adams" , "");
VerifyNameExpansion(" Jake Brown ", "Mr. Jake Brown III", "");
VerifyNameExpansion("No Such Guy" , ""                  , "no match found");

유사하게, C 스타일 구조체 배열에서도 정렬은 필드 간 관계를 명확히 한다.

struct Command {
    const char* name;
    void*       flag;
    CmdHandler  handler;
};

Command commands[] = {
    { "timeout",       NULL,               cmd_spec_timeout     },
    { "timestamping",  &opt.timestamping,  cmd_boolean          },
    { "tries",         &opt.ntry,          cmd_number_inf       },
    { "useproxy",      &opt.use_proxy,     cmd_boolean          },
    { "useragent",     NULL,               cmd_spec_useragent   },
};

논리적 블록 단위로 선언 그룹화

클래스 내 메서드나 변수는 역할에 따라 섹션으로 나누면 탐색이 쉬워진다. 각 섹션은 주석으로 목적을 명시한다.

class FrontendServer {
 public:
    // 사용자 프로필 관련 요청 처리
    void ViewProfile(HttpRequest* request);
    void SaveProfile(HttpRequest* request);

    // HTTP 응답 유틸리티
    string ExtractQueryParam(HttpRequest* request, string param);
    void ReplyOK(HttpRequest* request, string html);
    void ReplyNotFound(HttpRequest* request, string error);

    // 데이터베이스 연결 지원
    void OpenDatabase(string location, string user);
    void CloseDatabase(string location);
};

단락별 주석으로 흐름 강조

함수 내부 코드도 자연어 문단처럼 구분하면, 독자는 각 블록의 의도를 빠르게 파악할 수 있다.

def suggest_new_friends(user, email_password):
    # 1. 친구 목록에서 이메일 수집
    friends = user.friends()
    friend_emails = {f.email for f in friends}

    # 2. 이메일 계정 연락처 가져오기
    contacts = import_contacts(user.email, email_password)
    contact_emails = {c.email for c in contacts}

    # 3. 친구가 아닌 연락처 매칭
    candidates = contact_emails - friend_emails
    suggestions = User.objects.filter(email__in=candidates)

    # 4. 결과 페이지에 전달
    display.update({
        'user': user,
        'friends': friends,
        'suggested_friends': suggestions
    })
    return render("suggestions.html", display)

스타일보다 일관성이 우선

코드 스타일은 팀 내에서 일관되게 유지하는 것이 중요하다. 다음 두 가지 클래스 선언 스타일 모두 유효하지만, 하나를 선택하고 지속해야 한다.

class Logger {
    // ...
};

// 또는

class Logger
{
    // ...
};

개인 취향보다는 프로젝트 전체의 형식 통일이 더 큰 가치를 지닌다. 자동 포매터(linter, formatter) 도입은 이러한 일관성을 보장하는 데 효과적이다.

태그: 코드 가독성 코드 스타일 리팩토링 소프트웨어 설계 코드 정렬

6월 24일 17:31에 게시됨