개발 지식 책

클린 코드: 가독성 높고 유지보수 쉬운 코드를 위한 실천 전략 도서 리뷰

강코의 코딩 일기 2026. 4. 14. 18:29
반응형

"클린 코드" 도서를 직접 읽고 실무에 적용해 본 경험을 공유합니다. 변수명부터 함수, 객체, 테스트까지, 가독성 높고 유지보수 쉬운 코드를 만드는 핵심 전략과 그 효과를 상세히 다룹니다.

📑 목차

클린 코드: 가독성 높고 유지보수 쉬운 코드를 위한 실천 전략 도서 리뷰 - code, coding, computer, data, developing, development, ethernet, html, programmer, programming, screen, software, technology, work, code, code, coding, coding, coding, coding, coding, computer, computer, computer, computer, data, programming, programming, programming, software, software, technology, technology, technology, technology

Image by Pexels on Pixabay

왜 클린 코드인가? 지저분한 코드가 만드는 문제점

개발자라면 누구나 한 번쯤은 이런 경험을 해봤을 겁니다. 오랜 시간 공들여 작성한 코드를 며칠 뒤에 다시 봤을 때, 마치 남이 짠 코드처럼 낯설게 느껴지는 경험 말이죠. 혹은 다른 동료가 작성한 코드를 이해하기 위해 수많은 시간을 들여야 했던 경험도 있을 겁니다. 저 역시 그랬습니다. 처음에는 ‘돌아가기만 하면 돼’라는 생각으로 코드를 작성했고, 당장 눈앞의 기능 구현에만 급급했습니다. 하지만 프로젝트가 커지고 팀원들과 협업하는 과정에서, 이런 방식이 얼마나 큰 문제로 돌아오는지 뼈저리게 느꼈습니다.

지저분한 코드는 단순히 보기 싫은 것을 넘어, 실제 개발 프로세스에 치명적인 영향을 미칩니다. 버그를 찾고 수정하는 데 드는 시간이 기하급수적으로 늘어나고, 새로운 기능을 추가하려 해도 기존 코드와의 복잡한 의존성 때문에 엄두를 내지 못하게 됩니다. 결국 이런 기술 부채(Technical Debt)는 개발 속도를 늦추고, 팀원들의 사기를 저하시키며, 장기적으로 프로젝트의 실패로 이어질 수 있습니다.

저는 이런 문제에 부딪히면서 자연스럽게 클린 코드의 필요성을 절감했습니다. 그리고 많은 개발자 선배들이 추천하는 고전, 로버트 C. 마틴의 『클린 코드』를 집어 들었습니다. 이 책은 단순히 코드를 예쁘게 작성하는 방법을 넘어, 개발자의 사고방식과 태도를 변화시키는 데 큰 영감을 주었습니다. 책을 읽고 실무에 적용하면서 겪었던 변화들을 지금부터 자세히 공유하고자 합니다.

이름 짓기의 기술: 코드를 읽는 사람을 위한 배려

변수, 함수, 클래스 이름에 의도를 담는 법

『클린 코드』에서 가장 먼저 강조하는 부분 중 하나가 바로 이름 짓기입니다. 처음에는 '이름 하나 짓는 게 뭐 그리 중요하다고?' 생각했지만, 책의 예시와 설명을 따라가며 제가 얼마나 안일하게 이름을 지어왔는지 깨달았습니다. 코드에서 이름은 단순히 식별자가 아니라, 그 코드의 의도를 드러내는 핵심적인 수단입니다. 의도를 드러내지 못하는 이름은 코드를 읽는 사람에게 불필요한 인지 부하를 안겨줍니다.

예를 들어보겠습니다. 어떤 메서드에서 경과 시간을 계산해야 하는데, 단순히 int d; 라고 변수명을 지었다고 가정해봅시다. 이 변수가 무엇을 의미하는지 알기 위해서는 해당 변수가 사용되는 모든 코드를 찾아야 합니다. 하지만 int elapsedTimeInDays; 또는 int daysSinceCreation; 이라고 이름을 지었다면 어떨까요? 변수명만으로도 이 변수가 ‘생성일로부터 경과한 일수’를 의미한다는 것을 명확하게 알 수 있습니다. 이 작은 차이가 코드의 가독성에 엄청난 영향을 미칩니다.

제가 실무에서 겪었던 비슷한 사례로는, 데이터베이스에서 특정 조건에 맞는 사용자 목록을 가져오는 함수가 있었습니다. 처음에는 getUsers(); 라고만 지었는데, 나중에 보니 조건이 계속 추가되면서 getUsers(true, false, "admin"); 이런 식으로 호출되는 것을 발견했습니다. 이 함수 호출만으로는 무엇을 의미하는지 전혀 알 수 없었죠. 책에서 배운 대로 명확한 의도를 담아 getActivatedAdminUsers(); 또는 getUsersByRoleAndStatus(UserRole.ADMIN, UserStatus.ACTIVE); 와 같이 리팩토링했습니다. 이렇게 바꾼 후에는 코드를 이해하는 속도가 훨씬 빨라졌고, 새로운 팀원도 빠르게 코드의 맥락을 파악할 수 있었습니다.


// 나쁜 예: 의도를 알 수 없는 변수명
public List<int[]> getThem() {
    List<int[]> list1 = new ArrayList<int[]>();
    for (int[] x : theList) {
        if (x[0] == 4) {
            list1.add(x);
        }
    }
    return list1;
}

// 좋은 예: 의도를 드러내는 변수명과 함수명
public List<Cell> getFlaggedCells() {
    List<Cell> flaggedCells = new ArrayList<Cell>();
    for (Cell cell : gameBoard) {
        if (cell.isFlagged()) {
            flaggedCells.add(cell);
        }
    }
    return flaggedCells;
}
    

컨벤션과 일관성도 중요합니다. 특정 도메인에서 사용하는 용어는 통일하고, 약어 사용은 최소화하며, 동일한 개념에는 항상 동일한 이름을 사용해야 합니다. 이런 원칙들을 지키기 위해 팀 내 코드 리뷰 시 이름 짓기에 대한 피드백을 적극적으로 주고받기 시작했고, 점차 팀 전체의 코드 품질이 향상되는 것을 경험했습니다.

함수와 객체: 간결함과 응집도를 높이는 설계 원칙

단일 책임 원칙과 작은 함수의 힘

『클린 코드』는 함수를 작게 만들고, 각 함수가 단일 책임 원칙(SRP, Single Responsibility Principle)을 갖도록 설계하라고 강조합니다. 이 원칙은 하나의 함수나 클래스는 오직 하나의 변경 이유만을 가져야 한다는 의미입니다. 처음에는 함수를 너무 잘게 쪼개면 코드가 길어지고 복잡해지는 것이 아닌가 하는 의구심도 들었습니다. 하지만 실제로 적용해 본 결과, 장점이 훨씬 많다는 것을 깨달았습니다.

작은 함수는 가독성을 극대화합니다. 함수 이름만으로도 어떤 작업을 하는지 명확하게 알 수 있으며, 함수의 내부 로직을 파악하는 데 드는 시간도 현저히 줄어듭니다. 또한, 테스트 용이성이 높아집니다. 특정 기능에 문제가 발생했을 때, 작은 함수들은 문제의 원인을 파악하고 수정하기 훨씬 쉽습니다. 불필요한 의존성이 줄어들기 때문이죠.

제가 담당하던 백엔드 API 로직 중에는 사용자 인증, 데이터 유효성 검사, 비즈니스 로직 처리, 데이터베이스 저장까지 한 함수에서 모두 처리하는 경우가 많았습니다. 이 함수는 수백 라인에 달했고, 새로운 요구사항이 생길 때마다 수정하기가 두려웠습니다. 책에서 배운 대로 이 함수를 authenticateUser(), validateUserData(), processOrder(), saveOrder() 등으로 분리했습니다. 각 함수는 5~10줄 내외로 매우 간결해졌고, 각자의 책임만을 수행하도록 만들었습니다. 이렇게 분리하니 코드 변경 시 영향 범위를 예측하기 쉬워졌고, 디버깅 시간도 크게 단축되었습니다.

객체 지향 프로그래밍(OOP)의 원칙도 중요합니다. 클래스는 데이터를 숨기고, 오직 퍼블릭 메서드를 통해서만 데이터에 접근하도록 해야 합니다. 이는 캡슐화를 통해 데이터의 무결성을 보장하고, 외부에서 객체의 내부 구현에 직접적으로 의존하는 것을 막아줍니다. 또한, 클래스는 응집도(Cohesion)가 높고 결합도(Coupling)가 낮아야 합니다. 관련 있는 데이터와 동작은 한 클래스에 모아두고(높은 응집도), 다른 클래스와의 의존성은 최소화(낮은 결합도)해야 합니다.

이 원칙들을 적용하면서, 기존의 "데이터 컨테이너" 역할만 하던 클래스들을 "행동하는 객체"로 변화시키기 시작했습니다. 예를 들어, Order 클래스에 calculateTotalPrice(), addOrderItem(), cancelOrder() 같은 메서드를 추가하여 주문과 관련된 모든 비즈니스 로직을 Order 객체 내부에 캡슐화했습니다. 이는 도메인 모델의 표현력을 높이고, 서비스 계층의 로직을 간결하게 유지하는 데 큰 도움이 되었습니다.

주석과 포맷팅: 오해를 줄이고 이해를 돕는 도구

주석은 최소한으로, 포맷팅은 일관되게

『클린 코드』는 주석에 대해 매우 엄격한 입장을 취합니다. "주석은 나쁜 코드를 보충하는 변명"이라고까지 말하며, 주석 없이도 코드가 스스로 설명되도록 자체 문서화 코드를 작성하는 것이 가장 좋다고 강조합니다. 처음에는 이 말이 이해되지 않았습니다. '주석이 많아야 코드를 이해하기 쉬운 것 아닌가?'라고 생각했습니다. 하지만 실제로 주석이 많은 코드를 유지보수하면서, 주석이 오히려 혼란을 가중시키는 경우가 많다는 것을 경험했습니다.

오래된 주석은 코드가 변경되면서 더 이상 유효하지 않게 되거나, 실제 코드와 다른 내용을 담고 있는 경우가 허다합니다. 이런 낡은 주석은 개발자에게 잘못된 정보를 전달하여 오히려 버그를 유발하거나 디버깅 시간을 늘립니다. 저 역시 불필요한 주석을 과감히 제거하고, 대신 변수명과 함수명을 의미 있게 바꾸고, 코드를 작은 단위로 분리하여 그 자체로 설명이 되도록 노력했습니다.

물론 주석이 필요한 경우도 있습니다. 법적인 문제, 특정 라이브러리 사용의 한계, 성능 최적화를 위한 불가피한 선택 등 코드만으로는 설명하기 어려운 맥락이 있을 때 주석은 유용합니다. 하지만 이런 주석은 최소한으로 사용하고, 반드시 최신 상태를 유지해야 합니다.

코드 포맷팅 또한 클린 코드의 중요한 부분입니다. 일관된 포맷팅은 코드를 읽기 편하게 만들고, 팀원 간의 협업을 원활하게 합니다. 『클린 코드』는 특정 포맷팅 스타일을 강요하기보다는, 팀 내에서 합의된 규칙을 정하고 이를 일관되게 적용하는 것이 중요하다고 말합니다. 저는 팀에 합류한 이후, 코드 컨벤션 문서를 정비하고 PrettierESLint와 같은 도구를 도입하여 코드 포맷팅을 자동화했습니다. 이를 통해 불필요한 코드 스타일 논쟁을 줄이고, 모든 팀원이 동일한 포맷팅으로 코드를 작성하게 되었습니다. 결과적으로 코드 리뷰 시 본질적인 로직에 더 집중할 수 있게 되었고, 팀의 생산성이 향상되었습니다.

클린 코드: 가독성 높고 유지보수 쉬운 코드를 위한 실천 전략 도서 리뷰 - code, html, digital, coding, web, programming, computer, technology, internet, design, development, website, web developer, web development, programming code, data, page, computer programming, software, site, css, script, web page, website development, www, information, java, screen, code, code, code, html, coding, coding, coding, coding, coding, web, programming, programming, computer, technology, website, website, web development, software

Image by jamesmarkosborne on Pixabay

오류 처리와 경계: 견고한 시스템을 위한 방어 전략

예외 처리의 중요성과 경계 객체 활용

오류 처리클린 코드에서 매우 중요한 부분입니다. 프로그램은 예상치 못한 상황에 항상 대비해야 하며, 에러가 발생했을 때 적절하게 처리하지 못하면 시스템 전체가 불안정해질 수 있습니다. 『클린 코드』는 오류를 무시하거나, 오류 코드를 반환하는 대신, 예외(Exception)를 사용하는 것을 권장합니다. 예외는 오류를 명확하게 알리고, 호출 스택을 통해 오류의 발생 위치를 추적하기 쉽게 만들어줍니다.

저도 초기에는 오류가 발생하면 return -1;과 같은 오류 코드를 많이 사용했습니다. 하지만 이는 호출하는 쪽에서 항상 오류 코드를 확인해야 하는 번거로움이 있었고, 개발자가 실수로 확인을 누락하면 치명적인 버그로 이어질 수 있었습니다. 『클린 코드』를 읽은 후에는 예외를 적극적으로 활용하기 시작했습니다. 특히, 비즈니스 로직과 관련된 예외는 커스텀 예외 클래스를 만들어 명확하게 구분하고, 각 예외에 대한 처리 방식을 정립했습니다.

예를 들어, 사용자 입력값이 유효하지 않을 경우 InvalidInputException을, 데이터베이스에서 특정 데이터를 찾지 못했을 경우 ResourceNotFoundException을 발생시키도록 변경했습니다. 이렇게 하니 에러 발생 시 시스템의 복원력이 높아졌고, 에러 로그를 분석하여 문제점을 파악하는 시간도 크게 줄었습니다.

또한, 『클린 코드』는 경계(Boundaries)를 다루는 방법을 설명합니다. 경계는 외부 시스템이나 서드파티 라이브러리와 상호작용하는 코드 영역을 의미합니다. 외부 코드는 우리가 완벽하게 통제할 수 없기 때문에, 예측 불가능한 동작을 할 가능성이 있습니다. 책에서는 이러한 경계를 캡슐화하여 시스템의 다른 부분에 미치는 영향을 최소화하라고 조언합니다.

저는 외부 API를 연동하는 모듈에서 이 개념을 적용했습니다. 외부 API의 응답 형식이 변경될 경우, 시스템 전체에 영향을 미치지 않도록 어댑터 패턴을 사용하여 경계 객체를 만들었습니다. 외부 API 호출 로직을 별도의 클래스로 분리하고, 내부 시스템에서는 이 어댑터 인터페이스만을 사용하도록 했습니다. 이렇게 함으로써 외부 API의 변경이 내부 시스템에 미치는 영향을 이 경계 객체 안으로 제한할 수 있었고, 시스템의 유연성안정성을 높일 수 있었습니다.

테스트 코드: 클린 코드의 완성도를 높이는 필수 요소

클린 코드를 지탱하는 견고한 테스트

『클린 코드』는 테스트 코드의 중요성을 매우 강조합니다. 사실 이 책을 읽기 전에는 테스트 코드를 작성하는 것을 부가적인 작업으로만 여겼습니다. '당장 기능 구현하기도 바쁜데 언제 테스트 코드까지...'라는 생각이었죠. 하지만 책을 통해 테스트 코드 역시 프로덕션 코드만큼이나 중요하며, 심지어 프로덕션 코드의 일부라는 인식을 갖게 되었습니다.

클린한 테스트 코드는 다음과 같은 특징을 가집니다. 첫째, 가독성이 높아야 합니다. 테스트 코드를 읽는 것만으로도 해당 코드가 어떤 기능을 수행하고, 어떤 결과를 기대하는지 명확하게 알 수 있어야 합니다. 둘째, 신뢰성이 높아야 합니다. 테스트는 항상 동일한 결과를 반환해야 하며, 환경에 따라 실패하거나 성공해서는 안 됩니다. 셋째, 빠르게 실행되어야 합니다. 테스트가 느리면 개발자들이 자주 실행하지 않게 되고, 결국 무용지물이 됩니다.

저는 책에서 제시하는 F.I.R.S.T 원칙(Fast, Independent, Repeatable, Self-Validating, Timely)을 기반으로 테스트 코드를 작성하기 시작했습니다. 특히 테스트 주도 개발(TDD, Test Driven Development) 방식에 큰 영향을 받았습니다. 먼저 실패하는 테스트를 작성하고, 그 테스트를 통과할 만큼의 최소한의 프로덕션 코드를 작성한 후, 코드를 리팩토링하는 과정을 반복했습니다. 이 방식은 처음에는 다소 비효율적으로 느껴졌지만, 점차 코드의 품질을 향상시키고 버그를 줄이는 데 매우 효과적이라는 것을 깨달았습니다.

실제로 테스트 코드를 작성하면서 다음과 같은 변화를 경험했습니다. 이전에는 기능을 추가하거나 리팩토링할 때마다 혹시 모를 사이드 이펙트에 대한 불안감이 컸습니다. 하지만 회귀 테스트 역할을 하는 테스트 스위트가 구축되자, 자신감을 가지고 코드를 변경할 수 있게 되었습니다. 작은 단위의 함수들을 테스트 가능한 형태로 만들기 위해 자연스럽게 단일 책임 원칙을 지키게 되었고, 이는 곧 프로덕션 코드의 모듈화응집도 향상으로 이어졌습니다. 테스트 코드는 클린 코드를 유지하는 안전망이자, 코드의 명세서 역할을 톡톡히 해냈습니다.

클린 코드: 가독성 높고 유지보수 쉬운 코드를 위한 실천 전략 도서 리뷰 - coding, computer, hacker, hacking, html, programmer, programming, script, scripting, source code, coding, coding, coding, coding, computer, computer, hacker, hacker, hacker, hacker, hacker, hacking, hacking, programming, programming

Image by Pexels on Pixabay

클린 코드를 실천하며 얻은 변화와 앞으로의 과제

『클린 코드』를 읽고 실무에 적용하면서, 저와 팀은 많은 변화를 겪었습니다. 단순히 코드가 깔끔해진 것을 넘어, 개발 프로세스 전반에 긍정적인 영향을 미쳤습니다.

항목 클린 코드 적용 전 (지저분한 코드) 클린 코드 적용 후
코드 이해 시간 새로운 기능 파악에 2~3시간 소요 새로운 기능 파악에 30분 이내 소요 (약 4~6배 단축)
버그 발견 및 수정 원인 파악에만 수 시간, 수정 후 재발 가능성 높음 테스트 코드와 명확한 로직 덕분에 빠르게 원인 파악 및 수정, 재발률 감소
기능 추가/변경 기존 코드의 복잡성 때문에 변경에 대한 부담이 큼, 사이드 이펙트 우려 모듈화된 코드와 테스트로 자신감 있게 변경 가능, 변경 시간 30% 이상 단축
신규 팀원 온보딩 코드 베이스 파악에 2~3개월 소요 명확한 코드와 문서화로 1개월 이내 생산성 발휘
장기적 유지보수 비용 기술 부채 증가, 예측 불가능한 유지보수 비용 발생 기술 부채 감소, 안정적인 시스템 운영으로 유지보수 비용 절감

위 표에서 볼 수 있듯이, 클린 코드는 단기적인 노력으로 끝나지 않고 장기적으로 개발 생산성코드 품질을 비약적으로 향상시키는 기반이 됩니다. 특히 팀원 간의 협업 효율성이 크게 높아졌습니다. 이제는 다른 팀원의 코드를 이해하는 데 드는 시간이 줄어들었고, 코드 리뷰도 더욱 건설적인 방향으로 진행되고 있습니다.

물론 클린 코드를 완벽하게 실천하는 것은 끊임없는 노력과 학습이 필요한 과정입니다. 모든 상황에 100% 적용할 수 있는 만능 공식은 없으며, 때로는 비즈니스 요구사항과 트레이드오프를 해야 할 때도 있습니다. 하지만 클린 코드의 원칙들을 꾸준히 상기하고 적용하려 노력하는 것이 중요합니다.

이 책은 저에게 "좋은 개발자"가 되기 위한 길을 제시해 주었습니다. 단순히 기능을 구현하는 것을 넘어, 유지보수하기 쉽고, 확장 가능하며, 팀원들과 함께 성장할 수 있는 코드를 작성하는 것이 얼마나 중요한지 깨닫게 해주었습니다. 아직 갈 길이 멀지만, 『클린 코드』는 앞으로의 개발 여정에서 제가 계속해서 붙잡고 나아갈 나침반과 같을 것입니다.

마무리하며: 클린 코드는 선택이 아닌 필수

『클린 코드』는 단순히 코딩 스타일 가이드가 아닙니다. 소프트웨어 장인정신(Software Craftsmanship)을 기르기 위한 철학이자, 개발자로서 가져야 할 태도에 대한 지침서입니다. 이 책을 통해 저는 코드가 단순한 기계어가 아니라, 동료 개발자와의 소통 수단이라는 것을 절감했습니다. 가독성 높은 코드는 불필요한 오해를 줄이고, 유지보수하기 쉬운 코드는 미래의 나 자신과 팀을 위한 최고의 투자입니다.

혹시 아직 이 책을 읽지 않으셨거나, 지저분한 코드로 인해 고통받고 있다면, 『클린 코드』를 꼭 한 번 읽어보시길 강력히 추천합니다. 그리고 책에서 배운 원칙들을 작은 것부터라도 실무에 직접 적용해 보세요. 분명 놀라운 변화를 경험하실 수 있을 겁니다. 여러분의 개발 여정에 이 글이 조금이나마 도움이 되었기를 바랍니다.

여러분은 어떤 클린 코드 원칙을 가장 중요하게 생각하시나요? 또는 클린 코드를 실천하면서 겪었던 특별한 경험이 있으신가요? 댓글로 자유롭게 의견을 공유해 주세요!

📌 함께 읽으면 좋은 글

  • [클라우드 인프라] EKS AKS GKE 비교 분석: 클라우드 쿠버네티스 서비스 선택 가이드
  • [개발 책 리뷰] 리팩토링 도서 리뷰: 유지보수성과 확장성을 높이는 코드 개선 전략
  • [개발 책 리뷰] 리팩토링 전략: 레거시 코드 개선을 위한 핵심 원칙과 실용 가이드

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.

반응형