1장 깨끗한 코드
1장에서는 좋은 코드와 나쁜 코드를 구분하는 능력을 배운다.
코드가 존재하리라
코드
는요구사항
을 상세히 표현하는수단
이며언어
다.- 기계가 실행할 정도로 상세하게 요구사항을 명시하는 작업, 이것이 프로그래밍이고, 이렇게 명시한 결과가 바로 코드다.
코드를 자동으로 생성하는 시대가 다가온다는 말이다. 그때가 되면 프로그래머는 필요가 없다. 영업 직원이 명세서에서 프로그램을 자동으로 생성하면 되니까.
이 책은 2008년에 쓰였지만, 이때에도 코드를 자동으로 생성하는 시대에 대해 논의되고 있었다는 게 놀랍다! 하지만, 로버트 C. 마틴은 이런 관점이 비정형적인 수학이 나오리라 기대하는 수학자와 비슷하다고 말한다. 우리가 시키는 대로가 아니라 원하는 대로 돌아가는 기계가 나오리라고 말이다. 요구사항을 모호하게 줘도 우리 의도를 정확히 꿰뚫어 프로그램을 완벽하게 실행하는 그런 기계 말이다. (이상향에 조금은 가까워졌을지도...)
창의력과 직관을 보유한 인간조차도 고객의 막연한 감정만 가지고는 성공적인 시스템을 구현하지 못한다. 따라서 요구사항을 상세히 명세하는 과정은 필수적이고, 제대로 명시한 요구사항은 코드만큼 정형적이며 테스트 케이스로 사용해도 좋다는 사실. 요구사항에 더욱 가까운 언어를 만들 수도 있고, 요구사항에서 정형 구조를 뽑아내어 도구로 만들 수도 있지만, 어는 순간에는 정밀한 표현이 필요하다. 그러므로 세상이 아무리 자동화된다고 하더라도 코드는 항상 존재하게 될 것이다.
나쁜 코드
르블랑의 법칙 (Leblance's Law)
Later equals never. 나중은 결코 오지 않는다. 한번 작성한 쓰레기 코드를 나중에 수정하는 일은 결코 없다.
우리는 모두 좋은 코드가 중요하다는 사실을 안다. 왜? 오랫동안 나쁜 코드에 시달려왔으니까. 나쁜 코드에 발목 잡혀 고생한 기억이 있는가? 조금이라도 프로그램을 짜봤다면 필경 수없이 경험했으리라. 우리는 나쁜 코드를 헤쳐 나간다. 엉킨 덩굴과 숨겨진 함정으로 가득한 늪지를 힘겹게 헤쳐 나간다. 단서나 실마리를 찾으려 발버둥 치지만 소용이 없다. 눈앞에는 무의미한 코드만 끝없이 펼쳐진다.
어째서 나쁜 코드를 짰는가? 급해서? 서두르느라? 아마 그랬으리라. 제대로 짤 시간이 없다고 생각해서, 코드를 다듬느라 시간을 보냈다가 상사한테 욕먹을까 봐, 지겨워서 빨리 끝내려고, 다른 업무가 너무 밀려 후딱 해치우고 밀린 업무로 넘어가려고... 모두가 겪어본 상황이다.
우리 모두는 자신이 짠 쓰레기 코드를 쳐다보며 나중에 손보겠다고 생각한 경험이 있다. 우리 모두는 대충 짠 프로그램이 돌아간다는 사실에 안도감을 느끼며 그래도 안 돌아가는 프로그램보다 돌아가는 쓰레기가 좋다고 스스로를 위로한 경험이 있다. 다시 돌아와 나중에 정리하겠다고 다짐했었다... 나중은 결코 오지 않는다.
나쁜 코드로 치르는 대가
나쁜 코드는 개발 속도를 크게 떨어뜨린다.
프로젝트 초반에는 번개처럼 나가다가 1-2년 만에 굼벵이처럼 기어가는 팀도 많다. 코드를 고칠 때마다 엉뚱한 곳에서 문제가 생긴다. 간단한 변경은 없다. 매번 얽히고설킨 코드를 해독
해서 얽히고설킨 코드를 더한다. 시간이 지나면서 쓰레기 더미는 점점 높아지고 깊어지고 커진다.
나쁜 코드가 쌓일수록 팀 생산성은 떨어진다.
생산성이 떨어지면 관리층은 아래와 같은 단계를 통해 나름대로 복구를 시도한다. 그러다가 생산성은 마침내 0에 근접하게 되며 회사가 망하게 되는 것이다.
인력 추가 투입 -> 시스템 설계 이해 떨어짐 -> 나쁜 코드 더 많이 양산 -> 생산성 더 떨어짐 -> 인력 추가 투입...
빨리 가려고 좋은 코드를 위한 시간을 들이지 않으면 결국 더 늦게 간다. 진짜 전문가는 나쁜 코드를 양산하면 기한을 맞추지 못한다는 것을 잘 안다. 기한을 맞추는 유일한 방법은, 빨리 가는 유일한 방법은, 언제나 코드를 최대한 깨끗하게 유지하는 습관이다.
깨끗한 코드란?
깨끗한 코드 = 예술. 깨끗한 코드를 작성하는 프로그래머는 빈 캔버스를 우아한 작품으로 바꿔 가는 화가와 같다.
깨끗한 코드를 구현하는 행위는 그림을 그리는 행위와 비슷하다. 그림을 보면 대부분의 사람은 잘 그려졌는지 엉망으로 그렸는지 안다. 그렇지만 잘 그린 그림을 구분하는 능력이 그림을 잘 그리는 능력은 아니다. 깨끗한 코드를 작성하려면 청결
이라는 힘겹게 습득한 감각을 활용해 자잘한 기법들을 적용하는 절제와 규율이 필요하다. 열쇠는 코드 감각
이다.
책에서는 깨끗한 코드에 관해 설명하기 위해 여러 노련한 프로그래머들의 의견을 인용한다.
비야네 스트롭스트룹 (C++ 창시자)
나는 우아하고 효율적인 코드를 좋아한다. 논리가 간단해야 버그가 숨어들지 못한다. 의존성을 최대한 줄여야 유지보수가 쉬워진다. 오류는 명백한 전략에 의거해 철저히 처리한다. 성능을 최적으로 유지해야 사람들이 원칙 없는 최적화로 코드를 망치려는 유혹에 빠지지 않는다. 깨끗한 코드는 한 가지를 제대로 한다.
깨끗한 코드는 보기에 즐거운
코드다. 잘 만든 오르골이나 잘 디자인된 차를 접할 때처럼 깨끗한 코드는 보는 사람에게 즐거움을 선사해야 한다.
나쁜 코드는 나쁜 코드를 유혹
한다. 나쁜 코드를 고치면서 오히려 더 나쁜 코드를 만든다는 뜻이다. 이는 깨진 창문 이론과 비슷하다. 창문이 깨진 건물은 누구도 상관하지 않는다는 인상을 풍긴다. 그래서 서 사람들도 관심을 끊는다. 창문이 더 깨져도 상관하지 않는다. 마침내는 자발적으로 창문을 깬다. 따라서 일단 창문이 깨지고 나면 쇠퇴하는 과정이 시작된다.
그래디 부치 (Object Oriented Analysis and Design with Applications 저자)
깨끗한 코드는 단순하고 직접적이다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다. 깨끗한 코드는 결코 설계자의 의도를 숨기지 않는다. 오히려 명쾌한 추상화와 단순한 제어문으로 가득하다.
그래디 부치는 가독성
을 강조한다. 깨끗한 코드는 잘 쓴 문장처럼 읽혀야 한다. 좋은 소설과 마찬가지로 깨끗한 코드는 해결할 문제의 긴장을 명확히 들어내야 한다. 긴장을 쌓으며 클라이맥스에 이르렀다가 명백한 해법을 제시하며 진장과 문제를 풀어야 한다. 독자가 "아! 당연하지!"라며 무릎을 탁 치도록!
데이브 토마스 (OTI 창립자이자 이클립스 전략의 대부)
깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다. 단위 테스트 케이스와 인수 테스트 케이스가 존재한다. 깨끗한 코드에는 의미있는 이름이 붙는다. 특정 목적을 달성하는 방법은 (여러 가지가 아니라) 하나만 제공한다. 의존성은 최소이며 명확히 정의한다. API는 명확하며 최소로 줄였다. 언어에 따라 필요한 모든 정보를 코드만으로 명확히 표현할 수 없기에 코드는 문학적으로 표현해야 마땅하다.
깨끗한 코드는 다른 사람이 고치기 쉬운
코드다. 읽기 쉬운 코드와 고치기 쉬운 코드는 엄연히 다르다. 따라서 디이브는 깨끗한 코드를 테스트 케이스와 연관 짓는다. 아무리 코드가 우아해도, 아무리 가독성이 높아도, 테스트 케이스가 없으면 고치기 쉬운 코드가 아니며, 깨끗한 코드라고 할 수 없다.
마이클 페더스 (Working Effectively with Legacy Code 저자)
깨끗한 코드의 특징은 많지만, 그중에서도 모두를 아우르는 특징이 하나 있다. 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌을 준다. 고치려고 살펴봐도 딱히 손댈 곳이 없다. 작성자가 이미 모든 사항을 고려했으므로. 고칠 궁리를 하다 보면 언제나 제자리로 돌아온다. 그러고는 누군가 남겨준 코드, 누군가 주의 깊게 짜놓은 작품에 감사를 느낀다.
한마디로 요약하면 주의
다. 깨끗한 코드는 주의 깊게 작성한 코드다. 누군가 시간을 들여 깔끔하고 단정하게 정리한 코드다. 세세한 사항까지 꼼꼼하게 신경 쓴 코드다.
워드 커닝햄 (위키, 피드, 익스트림 프로그래밍 창시자)
코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 되겠다. 코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 불러도 되겠다.
깨끗한 코드는 읽으면서 놀랄 일이 없어야 한다. 코드를 독해하느라 머리를 쥐어짤 필요가 없어야 한다. 읽으면서 짐작한 대로 돌아가는 코드가 깨끗한 코드다. 명백하고 단순해 마음이 끌리는 코드가 깨끗한 코드다. 각 모듈은 다음 무대를 준비한다. 모듈을 읽으면 다음에 벌어질 상황이 보인다. 이만큼 깨끗한 코드는 너무도 잘 짜놓은 코드라 읽는 이가 그 사실을 모르고 넘어간다. 모든 뛰어난 설계처럼 설계자가 코드를 어이없을 정도로 단순하게 설계했기 때문이다.
코드를 읽는 시간대 코드를 짜는 시간 비율이 10대 1을 훌쩍 넘는다. 새 코드를 짜면서 우리는 끊임없이 기존 코드를 읽는다. 그렇기 때문에 읽기 쉬운 코드가 매우 중요하다. 기존 코드를 읽어야 새 코드를 짜므로 읽기 쉬운 코드를 만들면 짜기도 쉬워진다. 주변 코드를 읽기가 어려우면 새 코드를 짜기도 어렵다. 그러므로 급하다면, 서둘러 끝내려면, 쉽게 짜려면, 읽기 쉽게 만들면 된다.
보이스카우트 규칙
캠프장은 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라.
시간이 지날수록 코드가 좋아지는 프로젝트에서 작업한다고 상상해 보라! 전문가라면 너무도 당연하지 않은가! 지속적인 개선이야말로 장인 정신의 본질이 아니던가?