좋은 코드

예전에 어떤 버그하나를 추적하고 있었다. 문제를 이해하려고 관련된 코드를 쭉 읽어내려가다보니 어느순간 짜증이 솟구쳐 올랐다. <이거는 어떤 자식이 코드를 짰길래 이딴식이야!> 하며 git 히스토리를 열어보니… 그건 몇년전 나였다. 아마도 릴리즈가 급한 나머지 코드의 퀄리티에 신경 안쓰고 일단 돌아가는것에 집중했던 시기였던것 같다. 같은 코드를 오랫동안 만지는 여러 개발자들이 비슷한 경험을 하지 않았을까?

대부분의 사람들은 동작하는 코드를 만들수 있다. 어떤 사람들은 <빠르게> 동작하는 코드를 만들수 있다. 그보다 적은 수의 사람들은 <이해할수 있는> 코드를 만든다. 소프트웨어 회사의 매출은 동작하는 프로그램에서 나오지만, 회사의 진짜 자산은 (커피만 마시고) 코드를 만들어낼수 있는 프로그래머와 그 사람들이 수년간 만들어낸 지식의 총체인 방대한 코드베이스다. 예를들어 2015년 기준 구글의 코드베이스는 20억 라인이라고 한다. 단기간의 성공을 위해 우선 동작하는 프로그램을 만들수는 있지만 SW조직의 수명은 코드의 퀄리티에서 결정된다. 코드를 만들때는 각자 자기의 성을 짓는것과 같다. 그런데 몇년후 자신이 만든 성에 들어가서도 우리는 길을 잃는다. 현실에서 회사는 남이 만든 초가집을 성이라 우기며 아름다운 탑을 몇개 더 붙이라고 요구한다.

“Programs must be written for people to read, and only incidentally for machines to execute.”
“코드는 남들에게 읽히는게 목적이지만, 종종 컴퓨터가 실행하기도 한다”

예전엔 코드가 화려할수록, 복잡해 보일수록 뛰어난 것이라 생각했다. 그런데 이전 블로그에서 설명한대로 프로그래머의 자존심으로 채워진 화려한 코드는 스타트업 하나쯤은 쉽게 무너뜨릴수 있다. 수년간 더 여러 팀에서 일하고 난 지금은 좋은 코드를 이렇게 정의한다.

<당연하게 읽히는 코드>

이전 회사에서 테크 리드로 있으면서 많은 코드를 리뷰했다. 팀원은 이제 갓 대학을 졸업한 어린이(?)부터 20년 경력의 백전노장까지 다양하게 구성되어 있었는데, 그 중 J는 특히 코드 퀄리티에 관심이 많았다. 경험도 많고 듣기로는 인터뷰를 퍼펙트로 통과했을정도로 스마트한 친구였다. 이 친구가 짠 코드를 읽으면 <와우> 이런 감탄사는 나오지 않는다. 단지 코드의 처음부터 끝까지 논리의 흐름이 너무나 당연하게 읽힌다. 마치 J가 만든 성안에 처음 들어가 구석구석 살펴 보는동안 그가 옆에서 친절하게 길을 안내해주는 느낌이다. 그런데 <당연하게 보이는 코드>를 만드는게 사실은 가장 어려운 것이다. J는 스스로 길을 안내하는 코드를 만들기 위해 속도를 희생했다. 그는 어떤때는 좀 답답하게 느껴질정도로 코드를 천천히 만들었다. 어떤때는 괜찮아 보이는 코드들도 처음부터 다시 하겠다고했다. 그렇게 나온 코드는 너무나 당연히 읽히기에 쉽게 이해할수 있었고 고칠 부분이 거의 없었다. 당연히 버그도 나오지 않았다.

이와 반대로 이제 막 학교를 졸업한 어린이(?) 엔지니어들의 코드는 읽으면서 감탄사가 나온다. 여과해 <아 이딴식으로도 생각을 하는구나> 이 정도로 표현해야겠다. 그 코드는 분명히 목적대로 정확하게 동작한다. 유닛 테스트도 충실하게 채워서 논리의 부분 부분을 모두 커버한다. 그런데 아무리 읽어도 당연하지가 않다. 이상하다. 코드가 자신의 논리 흐름을 스스로 설명하지 못한다. 비유하자면 조그만 초가집에 리뷰하러 들어갔는데 그게 미로같은 동굴의 초입이었던거다. 거기에 더해 주니어는 승진 욕심에 코드를 시니어보다 더 빠른 속도로 만들어낸다. 몇년전 여름에 잠깐 일했던 인턴은 열성이 넘쳤다. 아마도 짧은 인턴쉽 기간동안 어떻게든 강한 인상을 남기고 싶었을것이다. 그래서 그 인턴은 석달 내내 코드를 만들어대며 리뷰를 요청했다. 계속 만들어내는 그 이상한 코드를 몇시간씩 리뷰하다가 이런 생각이 들었다.

147255590836907.jpg
(물론 이렇게 얘기하지 않았다)

그런데 <당연하게 읽히는> 에서 당연하다는 것이 몹시 주관적이다. 내게 당연한것이 다른 사람에겐 이상할수 있다. 하지만 경험상 어느정도 퀄리티를 갖춘 시니어로 구성된 팀이라면 한 시니어에게 당연해 보이는 코드는 다른 대부분 시니어에게도 자연스럽다. 주니어의 눈으로 보기에 자기들끼리 밀어주고 당겨주고 하는것처럼 보일수도있다. 하지만 그런것이 아니다. 코드의 퀄리티를 높이는 요소는 객관적으로 정의내리기 어렵지만, 경험자 사이에서 수렴되는 <보면> 알수있는 퀄리티의 요소가 있다. 평점 9점의 영화가 왜 훌륭한지 이유는 관객마다 조금씩 다를수 있다. 그런데 모든 사람들이 <아 좋았어> 라고 공감하는 퀄리티가 있는것이다.

가장 중요한 퀄리티는 <추상화> (Abstraction) 이다. 추상화의 가장 큰 오해중 하나는 <추상화 그림>처럼 현실을 모호하게 표현하는 것이라 생각하는것이다. 추상화의 본질은 감출것은 감추고, 드러낼것은 드러내는 것이다. 좋은 코드는 읽는 사람에게 가장 적절한 추상화의 단계 (level of abstraction)를 선사한다. Class, Function, Variable의 이름과 관계를 통해서 리뷰어가 읽으며 예측하고있는 단계의 추상화를 바로 그 순간 보여주는것이다. 성으로 들어가는 리뷰어가 문같은 형태를 찾고있는데 문의 열쇠를 보여주는 것은 리뷰어를 혼란스럽게 만들뿐이다. 좋은 추상화는 리뷰어가 문 앞에 다가간 그 순간에 문의 열쇠를 보여주는것이다. 성의 문을 하나 하나 열때마다 그 레벨에서 예측가능하고 익숙한 컨셉으로 논리의 방을 설명하는것이다. 추상화의 각 레벨에서 모두에게 <익숙한 컨셉>으로 설명하기 위해서는 많은 코드를 읽는것이 필요하다. 비슷한 유형의 문제에 대해 사람들이 공통적으로 동의하는 코드의 패턴이있기 때문이다. 나는 코미디언 <코난 오브라이언>을 좋아하는데 그의 팟캐스트를 듣다보면 항상 킥킥대던 그가 종종 진지한 주제로 대화할때가 있다. 그건 다른 코미디언이 호스트로 나오는 에피소드들이다. 코난과 다른 코미디언은 서로 뛰어난 코미디의 요소에 대해 진지하게 질문하고 탐색한다. 시대를 앞서간 코미디언들의 <익숙한> 패턴을 알고 싶어서 얼마나 연구했는지 서로 나누는 그 에피소드를 들으며 <직업>이 무엇인지 새삼 생각하게된다. 프로그래머가 새로운 것을 모두에게 익숙하게 설명하는 그 <당연함>의 이면에는 많은 시간 읽어내려간 방대한 코드의 양이 있다.

단계적 추상화를 마스터한 경험자와 초보의 가장 큰 차이는 논리의 흐름을 What 과 How로 설명하는 차이다. 좋은 코드는 추상화의 단계가 깊어질때마다 <이것은 무엇(What)입니다> 를 반복하고 주니어의 코드는 <이것은 어떻게(How) 돌아갑니다>를 반복한다. 주니어의 코드를 리뷰할때면 <이것은 귀가 쫑긋합니다> <이것은 짖습니다> <이것은 귀엽습니다> 와 같은식으로 여러개의 <How>를 붙여 무언가를 설명한다. 그럼 나는 <이거 개야?> 묻고 주니어는 그제서야 <아 개네!> 깨닫는다. 처음부터 대상이 개라고 설명했다면 나는 개의 동작과 특성에 익숙하므로 노력없이 논리를 이해했을것이다 (최악의 경우는 저렇게 설명해놓고 고양이라고 우기는 상황이다). 표현하고자 하는 논리를 모두에게 익숙한 컨셉 (What)들 사이의 관계로 설명하는것은 OOP에 좀 더 가깝다. 또한 논리를 <선언 (Declaration)>의 연속으로 표현하는 함수형 프로그램도 이에 가깝다. 그러나 <What>과 <How>중 무엇을 강조하는지는 OOP, 함수형 언어보다 코드를 만드는 사람의 경험과 내제된 퀄리티에 더 관계가 있다.

“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” – Linux Tovalds
“안좋은 프로그래머는 코드에 대해 걱정한다. 좋은 프로그래머는 데이터 구조와 관계에 대해 걱정한다” – 리누스 토발즈

끝으로 어느 팀이든 좋은 코드를 마스터한 시니어만으로 구성되지 않는다. 프로그래밍팀은 하나의 마을이다. 거기엔 아름답고 웅장하게 세워진 성도 있고 이제 첫 삽을 떠본 주니어가 만든 초가집도 있다. 시니어의 역할은 주니어의 초가집 엉성한 부분을 지적하는것에서 끝나지 않는다. 진짜 마스터는 계속해서 자기 성을 짓는 사람이다. 주니어가 지켜보며 영감 (inspiration)을 얻을만큼 계속해서 조금 더 아름다운 성을 만드는 사람이다. 주니어의 초라한 집에서 훗날 성이 될수 있는 재능을 발견해 용기를 주는 사람이다.

https://twitter.com/sm_park

좋은 코드”에 대한 6개의 생각

  1. 좋은글 감사합니다 🙂 혹시 공개된 오픈 소스 중에서 가독성이 좋다고 느껴졌던 프로젝트가 있을까요?
    아직까지 코드리뷰 경험이 부족하다보니, 좋은 코드에 대한 식견이 부족해서 도움을 얻고자 합니다 🙂

    • 가능하면 업무에 관련된 오픈소스를 보는게 좋은것 같습니다. 구글에서 나오는 오픈소스 툴, 프로젝트이 좋을것 같네요. https://github.com/google
      예를들어 Java가 언어라면 Guava (loading cache, collection등) 같은것이 좋습니다.

      하지만 코드 퀄리티를 강조하는 좋은 팀에서 일하는게 가장 좋습니다 🙂

  2. 좋은 글 감사합니다. 초보 개발자라서 현재 업무에 대해 익히고 난 이후 앞으로 공부해야 할 방향을 정하지 못해서 헤매고 있었는데 방향을 잡는데 도움이 되었습니다 🙂

  3. 좋은 글 잘 읽었습니다.
    사실 소스코드처럼 어렵지 않은 보통 글도 비슷하더군요. 15 년 전에 썼던 글을 읽어보면, 이해가 안 되는 게 참 많아요. ^^;

  4. 개발자는 아니지만 가끔 들어와 글 읽으며 좋은 영감을 얻고 갑니다. 어떤 글은 올 때마다 읽기도 해요. 좋은 글 감사드려요.

  5. 좋은 글도 좋은 소스만큼 시간이 흐른뒤에 봐도 읽기 편하고 감탄하게 됩니다. 올 초에 봤는데 좋아서 반년뒤에 다시 읽어봤는데 뜨끔하면서 감탄하게 하는 글입니다. 감사합니다.

댓글 남기기