자바스크립트를 활성화 해주세요

[책 리뷰] 조엘 온 소프트웨어

 ·  ☕ 12 min read

본 리뷰는 조엘 온 소프트웨어 책에 대한 리뷰입니다.

이 책은 지식전달 목적의 교재보다는 개발자의 에세이에 가까운 책이므로 특별히 장단점 분석을 하지 않습니다. 또한 본 글에서 책의 내용과 설명 부분은 제 주관적인 해석이 포함되어 있으므로 저자의 의도와 일치하지 않을 수 있습니다.

읽은 계기

나는 이 책을 약 7~8년 전에 처음 접했었다. 그때 당시에는 1부 중간을 읽다가 말았던 것 같은데, 최근 이 책을 끝까지 읽었다. 7~8년 전이면 학부 4학년~대학원생(+회사 파트타임 근무 기간)일 때였는데, 당시에는 이 책이 코드 작성법에 대한 조언을 위주로 하는 책인줄 알았다. 왜냐하면 가장 인상깊은 내용이 러시아 페인트공 문제였기 때문이다. (참고로 원문에서는 Shlemiel the painter’s algorithm이라고 되어있는데, 의미로 해석한다면 실수가 잦은 페인트공의 알고리즘이라고 해석할 수 있겠다. 왜 실수가 잦은 사람이 러시아인으로 번역되었는지는 잘 모르겠다.)

그리고 이런 글로 시작한다는 것은, 드디어 끝까지 읽어봤기 때문이다. 끝까지 읽어보니 이 책을 지금 읽은 것이 가장 적절했다고 생각했다. 왜냐하면 책의 중반부터 다루는 내용은 코드를 잘 짜는 법보단 개발자로서 일을 잘 하는 법에 가깝기 때문이다. 학생때나 초급 개발자 시기에는 실제 프로젝트를 수행하며 생기는 경험이 부족하기 때문에 같은 내용을 읽었어도 느끼는 바가 적었을 것이다.

레거시 코드를 활용해야하는 이유에 대한 합리적 설득

이번에 읽으면서 제일 큰 깨달음을 얻은 부분이라면 레거시 코드를 활용해야 하는 이유에 대해 합리적인 설득 부분이다. 회사에서 참고한 기존 코드 뿐만 아니라 내가 이전 프로젝트에서 작성한 코드조차 싹 다 밀어버리고 처음부터 다시 작성하고 싶다는 생각이 강렬하게 들었다. 실제로 일부는 직접 다시 작성하는 경우가 있었는데 내 나름대로 합리적인 이유는 있었다. 기존 코드가 특정 환경에 너무 의존적이거나, 해당 코드를 라이브러리화 했을 때 라이브러리의 장점을 살리지 못하는 경우라던가, 안 좋은 설계로 구현한 코드임을 알게 되었을때 등의 이유였다. (모두 설계가 좋지 않았기 때문으로 수렴한다.)

최근 프로젝트는 핵심은 유지하고 API만 변경하거나, 가독성만 발전시키는 방향으로 리팩토링하는 식으로 최대한 레거시 코드를 활용하긴 했다. 하지만 “시간적 여유만 더 있었더라면 저 레거시 코드와 타협하지 않고 더 깨끗하게 작성할 수 있을텐데"같은 미련이 없진 않았다. 그런데 이 책에서는 코드를 새로 작성하는 것은 결코 해선 안될 일이라고 말한다. 핵심적인 근거는 3가지이다.

기본적으로 코드는 작성보다 읽는것이 더 어렵다

나는 이 부분을 내가 예전에 짰던 코드를 보며 공감할 수 있었다. 물론 과거에 비해 나는 조금 더 경험이 생기고, 지식이 쌓이고, 다른 코드도 많이 봤을테니 예전에 짰던 코드가 구려보이는 것은 당연할 것이다. 하지만 남이 짠것도 아니고 내가 짠 코드인데 “그땐 이걸 몰랐지, 이렇게 고치자” 수준이 아니라 “도대체 과거의 나는 코드에 뭔 짓을 한거지?” 같은 생각이 든다는 것이다. 남이 짠 코드가 구려보이면 그 사람 실력이 모자라다고 거만한 생각을 했겠지만, 고작 3개월 사이에 다시 읽어본 코드에서 이런 생각이 든다는 것은 읽는 입장에서는 모든 코드가 다 구려 보인다고 볼 수 있을 것 같다.

프로그램을 숲으로 비유하자면, 숲을 만들기 위해 묘목을 한번에 심고 다 같이 키워서 울창하게 하는 것이 아니라, 묘목 하나를 나무로 만들고, 그 나무를 기준으로 묘목을 추가로 심는 것을 반복해서 만들게 될 것이다. 당연히 나무 하나하나에 집중하면서 작성하다 보니 큰 숲의 관점으로 보기 힘든 것은 당연하다. 미래의 내가 엿먹으라고 이렇게 작성한게 아니라 이게 그때 당시에 최선이었을 것이라는 것이다. 글을 잘 쓰기 위해선 다 쓰고 읽어봐야 하는 것과 같은 이야기다. 하지만 보통 빌드한 프로그램을 돌려보고 동작을 확인하는 것에서 끝난다. 읽을 것을 고민하는 시간은 설계하는 시간이 거의 전부다. 작성하다 보면 당연하다 생각해서 주석도 쓰지 않는 경우도 많다.

물론 레거시 코드에는 기술부채도 분명 존재할 것이다. 마감이 급할 때 버그 수정을 위해 하드코딩한다던가, 바로 다음 프로젝트가 급해서 기술부채를 해결하지 못하고 프로젝트를 종료하는 등 레거시 코드의 품질 저하에는 여러 원인이 있을 수 있다. 하지만 이 상황은 나만 겪는 것이 아닐것이다. 나, 내 후임, 내 동료, 내 사수 모두 이런 저런 이유로 읽기 힘든 레거시 코드를 생성했을 것이다.

기존 코드는 여러 에러에 대처한 훌륭한 코드

다른 이유는 어느정도 간접적으로 눈치채고 있었다. 머리로 알겠는 것과 마음까지 완전히 바뀌는 것은 별개다보니 여전히 코드를 새로 작성하고 싶다는 욕구가 생기곤 했다. 하지만 이 설명을 보고 나니 체크메이트 당한 기분이었다. 버그 수정을 위해 급하게 작성한 코드는 가독성은 안 좋지만, 소프트웨어의 목적성이나 정확성은 보장한다. 여러 핑계를 대면서 코드를 처음부터 다시 작성한다면 똑같은 실수를 반복하게 될 것이다.

비슷한 관점에서 연상되는 글이 있다. 정확히 내가 생각하던 글은 아닌 것 같은데, 핵심은 코드를 변경할 때 테스트 코드는 안전을 보장하진 못해도 없을 때 생길 위험을 많이 줄여준다는 주장이었다. 그런데 코드를 처음부터 다시 작성하면 테스트 코드도 활용하지 못할 가능성이 높다. 위험을 줄여주는 테스트 코드조차 활용할 수 없으니, 기술 부채를 없애기 위해 시작한 작업이 오히려 다른 관점의 기술 부채를 생성할 수도 있다.

코드를 다시 작성하는 것은 민첩성이 떨어져 시장 지배력이 낮아질 수 있다

책에서는 넷스케이프가 코드를 갈아엎고 새로 짜다가 시장 점유를 놓친 이야기로 이 이유에 대한 설명을 보충한다. 위에서 내가 한 생각처럼 시간적 여유만 더 있었더라면은 개발자의 기준일 뿐, 그러다 제품 출시가 미뤄지고, 시장 점유율을 놓치는 이야기는 마치 상업성과 예술성에서 고민하는 예술가 모습을 보는 것 같다. 최소한 예술가는 예술성에 집중하면 이를 알아주고 가치를 높여주는 평론가라도 있지만, 프로그래머는 제품으로 내놓을 뿐 코드를 내놓지 않는다. (오픈소스 이야기는 바로 아래에서 할 것이다.) 취미로 코드를 작성한다면 몰라도 일하고 사업하는 입장에선 장인정신이 매번 옳은 마음가짐이 아닐 수도 있다.

물론 오픈소스 프로젝트들은 사업성과 거리가 멀어보인다. 하지만 자세히 보면 오픈소스들 간에도 경쟁하고, 도태되고, 살아남는 현상은 존재한다. 내가 생각하는 대표적인 예시는 jQueryYUI다. (내가 웹 개발을 전문적으로 하지 않으므로 좋은 예시가 아닐수도 있다.) 내 기억으론 둘 다 JavaScript를 보조하기 위한 라이브러리로 사용되었고, 지원하는 기능의 범위도 비슷하다. 지금은 jQuery도 구시대 기술로 취급받을 만큼 웹 개발 환경도 바뀐 상태지만, jQuery와 YUI의 인지도를 비교해보면 jQuery가 압도적일 것이다. jQuery는 2020년에도 업데이트가 되고 있지만, YUI는 2014년에 프로젝트가 종료되었다. YUI가 코드를 처음부터 다시 작성해서 도태된 것은 아니지만, 오픈소스들 나름의 경쟁이 있고, 예술성만으로 평가받는 분야가 아님을 이야기하고 싶었다. 오픈소스지만 전혀 인지도가 없다면 그냥 공개해놓은 프로젝트처럼 보일 것이다.

혹시 YUI에 대한 관심이 있을 사람을 위해 왜 YUI가 도태되고 종료되었는지를 분석한 글도 첨부한다.

소프트웨어 세계에선 만병통치 디자인도 없다

소프트웨어의 종류를 분야에 따라 다르게 구분을 하면서 각 분야별로 다른 개발 방법론을 적용해야 한다고 했다. 나는 이 중에서도 사용자와 소프트웨어의 관계, 디자인 관련된 설명에서 느끼는 바가 많았다. 이 책에서는 소프트웨어의 종류를 5가지로 분류했다.

  • 상품 소프트웨어
    말 그대로 상품으로 판매하는 소프트웨어로, 사용자는 불특정 다수이며, 해당 사용자의 도메인 지식(해당 소프트웨어 사용과 관련된 지식) 수준 또한 예측하기 어렵다. 또한 다른 경쟁 상품/대체재가 존재할 가능성이 높다.
  • 사내 소프트웨어
    회사 내부 & 관련 협력사에서 사용할 소프트웨어로, 사용자는 어느정도 한정된 인원이며, 대부분 도메인 지식을 잘 갖추고 있다고 생각할 수 있다.
  • 임베디드 소프트웨어
    특정 하드웨어에서 구동되도록 제한되어있으며, 최대한 단순화 된 입출력만을 사용하여 사용자와 상호작용한다. 하드웨어에 의존적이다보니 사용자에게 요구하는 도메인 지식의 깊이가 낮은 편이다. (소프트웨어 기준) 품질 기준은 다른 종류 소프트웨어보다 한참 높다. (문제를 고칠 기회조차 오지 않을 가능성이 있기 때문이다.) 성능적 제한으로 인해 우아한 코드보단 빠른 코드가 더 중요하다.
  • 게임 소프트웨어 (주로 패키지 게임을 말하는 듯)
    상품 소프트웨어의 일부지만, 기존 상품 소프트웨어와의 차이점이 있다. 화면, 키보드/마우스부터 내부 하드웨어 자원까지 독점에 가깝게 사용하는 구조로 동작한다. 버전 변화가 버그 수정같은 수준으로 한정적이다. 제품을 지속적으로 사용할 확률이 낮다. 이러한 복합적인 원인에 의해 임베디드 수준의 품질 기준을 요구하게 된다.
  • 일회성 소프트웨어
    귀찮은 일을 반복시키기 위해 급히 작성한 쉘 스크립트, 해당 소프트웨어가 자주 활용되거나 발전시킬 가치가 생기면 사내 소프트웨어의 형태로 변형된다.

특히 여기서 상품 소프트웨어와 사내 소프트웨어를 다루면서 디자인에 관한 관점도 언급한다. 과장해서 사내 소프트웨어는 더럽게 디자인해도 대체재가 없기 때문에 사용된다. 게다가 해당 소프트웨어를 반복적으로 사용할 수록 거기에 몸이 적응해서 시간이 갈수록 그 문제를 못 느끼게 된다.

나는 전문적인 디자인을 배우지도 않았고, 특히나 배색을 위한 색감은 거의 최악 수준이다. 하지만 내 나름대로의 디자인 철학이 있는데, “이거 어떻게 사용하는거에요?” 같은 질문을 듣지 말자 였다. 상품 소프트웨어를 개발하는 입장에서는 괜찮은 철학이지만 사내 소프트웨어를 개발할 때는 불필요하게 에너지를 낭비할 수도 있는 철학임을 인지할 수 있었다.

다른 관점으로 생각해 보면 상품 소프트웨어와 사내 소프트웨어의 관계는 입문용 제품과 전문가용 제품의 관계로 비유해 볼 수 있을 것 같다.

말단 프로그래머가 할 수 있는 일

말단이면서도 해내기에서는 말단 프로그래머가 회사를 변화시키기 위한 전략을 설명하고 있다. 요약하자면 좋은 향기가 나는 사람이 되라는 것이다.

회사 내부에서는 매우 오래 된 소스 관리 도구로 버전 관리를 하고 있었다. (보안상 문제가 될 수도 있어 특정하지는 않는다. 상당히 오래 된 소스 관리 도구인데 당신이 생각하는 그것은 아닐 것 같다.) 게다가 직원들도 해당 도구 사용법을 완벽히 숙지하지 못한 것인지, 각종 환장의 콜라보가 터져나오는 소리가 들리곤 했다.

  • A가 file.c라는 파일을 보고 있는데, 그거땜에 B라는 사람이 file.c를 수정을 못 하고 있다.
  • 소스의 접근 권한 관리가 실제 파일의 읽기/쓰기 권한과 연동되어서, 다른 에디터로 수정 시 소스 상태가 꼬인다.
  • A가 file.c를 수정하다가 예기치 않게 프로그램이 종료되었는데 서버에 권한이 꼬인 상태가 되어 직접 DB를 수정해줘야 한다.
  • A가 뭔가 수정을 했는데, B가 사용하려니 문제가 있다. 근데 B가 문제를 수정하지 못하고 A가 수정해줘야 한다.

일부는 정확하지 않은 상황일 수도 있다. (일부는 내가 겪었던 상황을 기억을 바탕으로 쓴 것이고, 일부는 직원들끼리 오가는 이야기에서 맥락을 파악한 것이다.) 그리고 글의 정황에서 눈치챘겠지만, 저런 상황이 계속 나오는데도 여전히 그 도구를 사용해왔다. 다행히(?) 나는 그 도구를 사용해야 할 상황이 적었는데, 어쨋든 소스 관리에 대한 대책이 필요해 보였다.

일단 대세는 git이었다. 대학원때나 파트타임으로 일할때는 SVN도 사용해봤었는데, 전문적으로 사용한 것은 아니었다. 내가 아는 git은 SourceForge처럼 코드를 가져오는 수단 정도였다. 사실상 git == github였다. (물론 둘의 차이는 알고 있었지만, 활용 수준에선 둘을 동일 개념으로 보는 수준이었다.) 나 혼자라도 해봐야겠다는 생각으로 시작했다.

1년차에는 git의 최소한의 사용법은 익혀서, 날짜 단위로 코드 형상에 대한 스냅샷을 보관하는 수준으로는 활용할 수 있었다. 구글링 하면서 더듬대긴 했지만 어쨋든 과거의 코드 형상을 다시 가져오는 등의 작업은 할 수 있었다.

2년차에 접어들 때, git을 좀 더 효율적으로 사용하기 위한 방법인 git-flow를 배웠다. Commit의 단위를 깔끔하게 나눈 것은 아니었지만, 내 코드의 흐름이 보이기 시작했다.

3년차에 접어들 때, 아예 git 관련 전문 강의를 수강했다. 처음엔 “인터넷에 뒤지면 튜토리얼부터 시작해서 자료가 많은데 굳이 이걸 돈 주고 들어야 할까?” 같은 생각으로 구글링만 갖고 독학하려 했다. 부족한 부분은 있었지만 “일단 나 혼자서는 형상 관리가 가능함” 수준까지는 된다고 판단했다. 하지만 회사에서 다른 사람한테 가르쳐주기엔 모자라다는 생각을 했고, 협업 관련 지식은 부족했기에 강의를 수강했다. 그 해에는 외부 교육 수강에 대한 지원조차 받지 못했지만, 내 사비로 수강했다. (기업 문화를 발전시키겠다는 대의보단 나라도 살고 봐야겠다는 의욕이 더 정확하지만.)

내가 git을 통해 편하게 일하는 듯한 향기를 풍기며 간접적으로 홍보했다. 매번 새로운 버전을 배포할 때 git log를 바탕으로 패치노트를 작성해서 전달했고, 버그의 원인 규명이나 수정도 효율적으로 했다. 문제의 그 소스 관리 도구와 연관된 프로젝트는 따로 내가 git 버전으로 포팅해서 보관했고, 그걸로 변경 이력에 대한 분석도 도와줬다.

마침내 1명은 git을 공부하기 시작했다. 공부할 때 필요한 자료도 찾아서 공유해줬고, 가끔 물어보면 아는대로 대답해줬다. 내가 판단하기에 그 1명정도는 바꾸는데 성공한 것 같았다. 고작 1명이냐 싶겠지만 코드를 수정하는 6명 중 1명을 바꿨다.

이거 15년 전에 출간된 책인데

간과하기 쉬운 사실은 이 책이 2005년에 출간된 책이라는 것이다. 심지어 이 책은 블로그 글을 잘 편집하고 번역한 것이며 실제 글의 작성 시기를 고려하면 거의 20년 전 글이다. 번역이 지금 보기에 완전 자연스럽진 않아도 읽는데 불편함이 없을 정도로 잘 번역되어있다. 그리고 책에서 언급하는 회사나 인물이 번역 당시에는 독자들이 잘 모를까봐 주석을 달아놨지만, 지금은 주석을 달지 않아도 될 만큼 국내에서도 유명한 존재라는 것도 재밌다. (Amazon의 제프 베조스, 밴엔제리 아이스크림 등) 두 기업을 롤 모델 방향에 관해 정리하면서 언급하는데 글의 작성 시기를 모른다면 그냥 성공한 기업에 본인 편한대로 해석한 느낌이 들 정도다. 성공하는 사람/회사를 알아보는걸까?

개발자로서 나를 돌아보게 되다

내가 팔랑귀일수도 있겠지만, 책을 보면서 개발자로서의 좌우명이 약간 변경되었다. 장인정신으로 깨끗하게 작성한 코드가 목적이었는데, 때와 상황에 맞게 유기적으로 변할 수 있는 개발자가 되어야겠다는 생각이 들었다. 기존의 좌우명은 정해진 기간, 적당한 상황 단위로 최선을 다 하되 평생 그러고 있다간 오히려 도태될 수도 있겠다는 생각이 들었다.

약간 안도감도 들었다. 내가 일하는 상황이나 고민이 이상한 것이 아니라 충분히 발생할 수 있다는 것, 해결을 위해 한 문제분석이나 가설, 해결법이 비슷한 것을 보고 “최소한 개발 업무는 정상적으로 했구나” 같은 생각이 들었다.

또한 내가 해 온 선택이 매번 옳은 것은 아니었지만, 몇몇 부분에서는 꽤 괜찮은 선택을 해왔음을 인정받는 느낌이 들었다. 솔직히 처음에는 나라도 살아남아야겠다로 시작했지만, 나중에는 사람들을 바꿀 수 없다면 내가 잘해서 바뀌고 싶게 만들자는 생각으로 해왔던 일이 이 책에서도 추천하는 방법일 줄은 몰랐다. (다른 사람들은 어떻게 생각하는지 모르겠지만…)


JaeSang Yoo
글쓴이
JaeSang Yoo
The Programmer

목차