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

Clean Code 1장: "깨끗한 코드" 정리

 ·  ☕ 11 min read

1장 깨끗한 코드를 읽으면서 내용에 대해 보충하거나, 개인적인 의견으로 반박하거나, 고민해 볼 부분에 대해 적어보려 한다.

코드가 존재하리라

내가 정확하게 기억하는 것인지 모르겠지만, 컴퓨터과학적으로 프로그래밍이 완전히 자동으로 대체될 수 없다고 한 내용을 봤던 것 같다. 문제는 어디에서 봤는지, 다시 찾으려면 어떤 키워드로 검색해야 하는지 기억이 안 난다는 거다.

조금 더 높은 단계의 추상화를 위해 새로운 도메인 언어가 나오고, 고급 언어가 나오지만 아직도 막연한 요구사항을 구현하는 기술은 나오지 않았다. 아직 자연어로 컴파일되거나 실행되는 프로그래밍 언어는 나오지 않은 것으로 알고 있다.

이미 최근에는 copilot이란 기술이 나와서 주석이나 함수 이름 등 문맥을 이해하고 코드를 생성해준다. 직접 경험해 보진 못했지만, 문맥에 따라 어느정도 패턴화 된 코드 블럭을 자동으로 제공해 주는 것으로 예상되는데, 결국 프로그래머가 개입을 해야한다는 사실은 아직까지 유지되는 것 같다.

비주얼 스튜디오에서도 자동으로 함수나 코드 일부를 작성해 주지만, MFC에서 이벤트 핸들러 함수 등록도 원하는 수준으로 자동화 되지 않아서 결국 내가 직접 수정해서 써 버릇 했다. (여러 요소를 반복으로 등록할 수 없는 문제, 원하는 위치에 등록할 수 없는 문제때문에 직접 수정했다.)

예전에 다른 과목 교수님이 우스갯소리로 하길, 설계 프로그램의 목적은 소프트웨어를 설계하는 것이지만, 실제로 가장 많이 사용되는 경우는 이미 작성한 코드로부터 구조를 읽어오기 위한 것이라고 했었다. 사양을 가장 잘 나타내는 문서는 코드라는 것에 대한 유사한 예시라고 할 수도 있겠다.

아무리 코드가 사양을 가장 잘 나타내는 문서라지만, 설계문서가 필요 없다는 것은 아니다. 왜 이런 식으로 설계가 되었는지는 코드 밖에서 서술하는 수 밖에 없다. 대부분 유연한 확장성을 위한 코드 구조를 설계하는데, 이 부분은 코드에서 쉽게 나타낼 수 없을 것이다.

나쁜 코드

르블랑의 법칙: 나중은 결코 오지 않는다.

당연한 사실이다. 프로젝트가 마감 기한을 끝내고 나면 리팩토링하면서 나쁜 코드를 수정할 기회가 오지 않는다. 사업 관점에서는 이미 요구사항을 만족했는데 왜 굳이 그걸 더 수정해야 하냐며 리팩토링 할 시간을 주지 않을 것이다.

불가능한 이야기지만, 처음부터 잘 짜야 한다. 그렇다면 차선책은 무엇일까? 나의 차선책은 수정하기 쉽게 짜야 한다. 고 생각한다.

나쁜 코드로 치르는 대가

나쁜 코드는 생산성을 떨어트린다. 생산성을 올리겠다고 사람을 더 투입하다간 브룩스의 법칙에 의해 생산성을 더 낮출 뿐이다.

레거시 코드를 보면서 밀어버리고 다시 짜고 싶다는 생각은 어찌 보면 당연한 것이다.

원대한 재설계의 꿈

결국 생산성 문제로 인해 새로 설계를 진행한다고 가정하자. 기존 생산성 낮은 프로젝트는 시장의 요구사항을 만족하며 계속 진행되긴 할 것이며, 새로운 설계 팀은 기존 프로젝트의 진행을 역전해야먄 완전히 대체될 수 있다. 아무리 레퍼런스 코드가 있다 한들 완전히 대체되는데 걸리는 시간은 길다. 빨리 역전하려고 서두를수록 기존의 실수를 범하기 쉽다. 결국 새로운 설계 프로젝트가 완성되더라도 밀어버리고 싶다는 생각이 다시 나오고, 반복된다.

대표적으로 넷스케이프의 몰락이야기를 들 수 있겠다. (완전 동일한 이야기는 아니지만 맥락상 비슷한 이야기가 될 것으로 보인다.)

웹 브라우저 시장을 잘 점유하던 넷스케이프는 넷스케이프 5부터 오픈소스화 하면서 코드를 공개했는데, 당시 코드가 너무 어렵다는 이유로 소스 코드를 다시 작성하기로 결정한다. 이 결정으로 넷스케이프는 다음 메이저 버전 배포가 늦어지고, 후에 출시한 넷스케이프 6는 준비가 덜 된 상태에서 출시한 수준이었다.

물론 넷스케이프의 몰락에는 인터넷 익스플로러 끼워팔기도 어느정도 영향을 줬지만, 코드를 밀고 다시 짜는 이야기가 나올때 거의 매번 언급되는 것을 볼 수 있다. (학교에서도 몇번 들었고, 조엘 온 소프트웨어 책에도 나온다.)

태도

깨끗한 코드가 중요한걸 알면서도 왜 굳이 더러운 코드로 작성하는가? 요구 사항이 바뀌기 때문에? 일정이 빡빡해서? 그런데 원인은 개발자 잘못이라고 한다.

위의 조건(요구사항 변화, 빡빡한 마감)을 만족하면서 코드를 작성하는 방법은 더럽게 짜는 방법밖에 없다고 관리자를 설득해야 한다고 한다. 코드 작성에는 내가 전문가이니, 당연히 전문가로서 관리자를 설득해야 한다고 한다.

의도는 알겠는데, 현실적으로 이런 설득이 먹혀들어가는 환경인지는 모르겠다. 대부분 그러면 야근으로 귀결되지 않나? 이런 설득이 안 통하는 경우에는 나쁜 직장이니 퇴사해야한다는 건가? 좋은 뜻으로 한 얘기겠지만, 약간 무책임해보이는 부분은 있다.

원초적 난제

기존에 어질러진 코드들이 개발 속도를 낮춘다.마감을 지키기 위해 코드를 더럽히는 수 밖에 없다는 압박감에 시달린다. 이 두가지 상반된 문장이 난제라는 것 같다.

하지만 진짜 전문가들은 마감을 지키기 위해 코드를 더럽히는 수밖에 없다는 것이 틀렸다고 한다. 결국 어지럽힌 코드가 내 생산성을 떨어뜨릴 것이라는것이다.

깨끗한 코드라는 예술?

그렇게 깨끗한 코드가 중요하다고 치고, 그럼 깨끗한 코드는 어떻게 작성하는데요? 어떻게 해야 깨끗한 코드인질 모르는데 어떻게 깨끗하게 짜요?

그림을 그리는 방법을 잘 몰라도, 어떤 그림이 좋은 그림이고, 나쁜 그림인지는 알수 있듯 깨끗한 코드를 작성하는 법을 몰라도 코드가 깨끗한지 더러운지는 판별할 수 있다는 것이다.

깨끗한 코드를 작성하는 감각이 있으면, 어지러운 코드를 봐도 어떤 방법으로 해결할 지에 대한 생각을 도와준다고 한다.

깨끗한 코드란?

오랜 경험을 한 다른 개발자들에게 깨끗한 코드란 뭐라고 생각하냐? 고 물어봤다고 한다.

Bjarne Stroustrup

C++ 언어의 창시자인 바야네 스트롭스트룹의 의견이다.

코드가 우아하고 효율적인 것을 좋아한다. 논리가 간단해야 버그가 쉽게 숨지 못하며, 유지보수를 용이하게 하기 위해 의존성이 최소화되어야 한다. 오류 처리는 명백한 전략에 따라 처리해야 한다. 성능을 최적으로 유지해야 사람들이 근본없는 최적화를 시도하지 않는다. 깨끗한 코드는 한가지 일을 잘 한다.

깨끗한 코드는 보기 즐거운 코드라 한다.

C++ 창시자 답게 성능에 대한 언급을 두번씩이나 하는데, 그 이면에는 불필요한 코드가 들어오지 못하게 하려는 의도가 있다고 생각한다.

코드가 점점 더 더러워 지는 현상에 대해서 깨진 유리창에 비유를 하는데 더러운 코드일수록 정이 안 가서 더 더럽게 된다. 는 얘기다.

Grady Booch

Object Oriented Analysis and Desing with Applications의 저자인 그래디 부치의 의견이다. (국내에는 UML을 활용한 객체지향 분석 설계로 번역되었다.)

깨끗한 코드는 간단하고 명료하다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다. 깨끗한 코드는 기획자의 의도를 어지럽히지 않으며, 명쾌한 추상화와 단순한 제어문으로 가득하다.

특히 가독성 관점에서 집중해 이야기하고 있는데, 명쾌한 추상화와 단순한 제어문 이야기하고 있다.

컴퓨터공학에서 추상화는 구현하고자 하는 대상의 핵심적인 특징을 가지는 모델을 뜻한다. 즉, 명쾌한 추상화와 단순한 제어문이라는 이야기는 필요한 내용만 작성된 코드를 뜻한다.

Dave Thomas

OTI의 창립자이자 이클립스 전략(아마도 IDE인 Eclipse의 오픈소스화 전략을 말하는 것 같다.)의 대부 데이브 토마스의 의견이다. (동명이인의 데이브 토마스는 실용주의 프로그래머의 공동 저자로, 다른 사람이다.)

깨끗한 코드는 원 저자가 아닌 다른 사람들도 읽고 발전시킬수 있다. 단위 테스트와 인수 테스트를 포함하고 있으며, 의미 있는 이름을 가지고 있다. 특정 목적을 달성하기 위한 방법이 하나만 제공된다. 명확하게 정의된 최소한의 의존성만 가지고 있으며, API는 명확하고 최소한으로 제공된다. 언어에 따라 필요한 모든 정보가 코드만으로 표현될 수 없기 때문에 코드는 문학적이어야 한다.

다른 사람이 변경하기 쉬워야 한다는 점에서 그래디 부치가 이야기한 가독성과 비슷하면서도 다른 이야기를 하고 있다. 코드가 읽기 쉬운 것과, 변경하기 쉬운것은 다른 문제이기 때문이다.

또한 테스트에 대한 이야기를 하는데, 과거에는 의문을 불러일으킬 이야기였을지 모르지만, 테스트 주도 개발이 활성화된 요즘, 테스트는 매우 중요하다.

최소한이란 단어도 자주 사용하는데, 이는 코드가 작은 것에 더 큰 가치를 두고 있는 것 같다.

테스트에 관한 이야기가 나와서 하는 말인데, 예전에 내가 오픈소스 기여 전략을 배울때도 테스트의 중요성을 이야기했었다. 테스트 코드는 코드의 안전성 확보 뿐만 아니라, 해당 코드의 함수/기능을 어떻게 사용하는지 보여주는 문서의 역할도 수행할 수 있다고 했다.

Michael Feathers

레거시 코드 활용 전략의 저자 마이클 페더스의 의견이다. (참고로 해당 책도 좋은 책이지만 번역이 좋지 않다는 의견이 있다.)

깨끗한 코드의 특징은 여러가지 있지만, 그 중 모든 것을 아우르는 특징이 하나 있다. 깨끗한 코드는 언제나 누군가 주의깊게 짰다는 느낌을 준다. 이미 작성자가 코드에서 모든 사항을 고려하여 작성했으며, 더 발전시키려 해도 딱히 발전시킬 거리가 보이지 않는다. 해당 코드라는 작품에 감사함을 느끼게 한다.

모든 사항을 고려해서 짰다는 말은 나에게는 두가지 의미로 해석된다.

첫번째는 방어적으로 프로그래밍을 했다는 것이다. 예를 들어 함수 API를 제공한다면, 잘못된 입력에 대한 적절한 예외처리, 코드 흐름상 오류가 날 수 없게 검증을 잘 한 코드라는 것이다. 문제가 생겼을 때 해당 API 내부를 의심하지 않아도 되게 작성했다고 볼 수 있다.

두번째는 각 기능의 동작 방식에 유연하게 대처할 수 있게 작성된 코드라는 것이다. 보통 유명한 API들은 각 함수의 기능 범위가 작은 편인데, 이는 정확하게 어느 단계에서 문제가 생긴 것인지 알기 쉽게 한다. 또한 멀티쓰레드 등의 환경에서도 문제 없도록 동기화 문제를 해결하고, 입출력시 상태를 쉽게 확인하고, 중간에 취소 등을 할 수 있도록 짧게 blocking하는 방식으로 작성되어있다.

Ron Jeffries

익스트림 프로그래밍의 창시자 중 한명인 론 제프리스의 의견이다.

켄트 백의 단순한 코드에 대한 규칙을 중요도 순으로 나타내면 아래와 같다.

  • 모든 테스트를 통과한다.
  • 중복이 없다.
  • 시스템의 모든 설계 아이디어를 표현한다.
  • 클래스, 메서드, 함수 등을 최소로 줄인다.

특히 이 중에서도 중복이 핵심이라 생각한다. 같은 일이 계속 반복된다면, 코드에서 표현이 잘 안되었다는 생각이 든다. 나는 이런 것을 찾아 더 명확하게 표현하려 한다.
나에게 표현력이란 의미 있는 이름이고, 이름을 정하기 까지 몇번이고 바꾸는 편이다. 이클립스같은 현대 개발환경에서 이름을 바꾸는 것은 별로 어렵지 않다. 물론 이름 뿐만 아니라 객체나 함수가 한가지 일만 수행하는지 확인한다. 만약 두가지 이상의 일을 수행한다면 이것을 분리해야 하며, 한가지 일만 수행하도록 변경한다.
중복을 줄이고, 표현력을 높이고, 단순하게 추상화하기. 이 방법으로 나는 깨끗한 코드를 만든다.

상당히 길게 예시까지 들어가며 의견을 제시했는데, 핵심은 마지막 문장으로 볼 수 있겠다.

Ward Cunningham

위키의 발명자, 익스트림 프로그래밍의 창시자 중 한명, 디자인 패턴의 원동력인 워드 커닝햄의 의견이다.

깨끗한 코드로 일을 할 때면, 각 루틴은 짐작한대로 수행한다. 해당 코드가 문제를 해결하기 위해 작성된 언어처럼 보인다면, 아름다운 코드라고 불러도 되겠다.

깨끗한 코드는 읽으면서 놀라는 일이 없어야 한다. 크게 노력하지 않아도 코드를 바로 이해할 수 있다. 너무 잘 작성된 코드는 잘 작성되었다는 사실조차 알아채기 힘들다.

우리들 생각

앞으로 이 책에서 깨끗한 변수명, 깨긋한 함수, 깨끗한 클래스를 작성하는 방법에 대해 알려줄 것이다.

무술을 예로 들면, 최고의 무술이 존재하지 않고, 각 관장이나 계파에 따라 다른 것을 배우게 된다. 절대적인 정답이 없으며, 가르치는 환경에 따라 배우는 것이 다르다.

당연히 이 책은 저자 기준으로 아는 방법을 가르칠 것이며, 해당 내용에는 논쟁의 여지가 있다. 하지만 이 책에서 설명하는 내용은 나름 저자가 오랫동안 숙고한 방식이다. 그러니 저자의 관점을 존중해 주길 바란다.

우리는 저자다

Javadoc에서@author 항목은 우리가 저자라는 것을 알려준다. 저자라는것은 독자가 있다는 것이며, 저자로서 독자들과 잘 소통하기 위한 책임이 있다. 앞으로 코드를 작성할 때, 저자로서의 노력을 평가할 독자들을 생각하면서 코드를 작성하라고 한다.

코드를 작성하는 것 보다 읽는데 시간이 더 많이 소모된다. 읽는 시간 대 작성 시간의 비율은 약 10:1정도다. 우리는 코드를 작성하면서도 이전의 코드 일부를 읽어야하기 때문이다.

결국 코드를 쉽게 작성하고 싶다면, 읽기 쉽게 작성하는 것이 중요하다.

보이스카우트 원칙

코드를 깨끗히 작성하는 것만으론 부족하다. 코드는 계속 깨끗하게 유지되어야 한다. 시간이 지남에 따라 코드가 점점 더러워진다.

보이스카우틑 원칙은 우리의 사명을 나타낸다고 생각한다.

캠프장을 오기 전보다 더 깨끗하게 해놓고 떠나라.

한번에 많은 노력을 들여 코드를 정리하지 않아도 된다. 변수 이름을 더 좋게 변경하거나, 큰 함수를 분리하거나, 작은 중복을 제거하거나, 복잡한 if문 하나 정리면 충분하다.

기타

책을 원서로 읽고 있는데, 내용을 정리하면 정리할 수록 내가 번역한 초안을 올리는 것 같아서 일부 너무 똑같은 내용은 좀 정리를 했다.

이 책의 다른 장도 중간중간 본 적이 있었는데, 기본적으로 좀 비현실적이거나 논란의 여지가 있어 보인다고 생각했다.

다행히 저자는 학파가 다른 것 처럼, 자신의 주장일 뿐이고, 그 의견을 존중하길 바라지만, 절대 정답이 아니라는 식으로 이야기하고 있다.

책의 내용을 참고하여 더 다양한 기법, 전략을 알아보고 각 상황에 맞는 적절한 기법을 사용해야겠다.


JaeSang Yoo
글쓴이
JaeSang Yoo
The Programmer

목차