Clean Code 주석 달기 - 1부

Seoyong Lee·2023년 4월 27일
0

개발 관련 생각들

목록 보기
6/9

You know you are working on clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem.
코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 클린 코드라 부를 수 있다.
코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 부를 수 있다.


Ward Cunningham - from 클린 코드

회사에서 1주간 Fix-it Week을 도입하기로 하였다. 지금까지 바쁘게 달려오기만 했다면 이제 우리가 작성한 코드를 뒤돌아 보고 기술 부채를 점검할 시간이다. 마침 그동안 앞 2-3개 챕터 이상 진도를 나가지 못했던 클린코드가 생각났다. 클린코드를 끝까지 읽어보고 다시 재해석한 내용을 적어보았다.

클린코드는 너무나 상투적이다

처음 입사하고 나서 팀의 코딩 규칙을 세울때 클린코드 내용을 TS 버전으로 압축한 요약본을 숭배했던 기억이 난다. 정확한 의미는 알지 못한채 그냥 하지 말라는 것은 피하고, 하라는 것만 따랐었다. 그때는 그것이 곧 클린코드라고 생각했다. 그런데 나중에 책을 보니 많은 생각과 예외를 글로 설명하고 있었다.

여기서 중요한 점은 '왜 이렇게 해야 할까?'라는 비판적 사고인 것 같다. 과연 나의 생각과 연결하여 100% 클린코드의 내용을 이해하였는가? 동의한다면 그 이유는 무엇인가? 동의하지 않는 경우는? 지금 생각해 보면 이런 생각 없이 무지성으로 따르기만 했던 것 같다.

그렇다면 이제 이러한 비판적 사고를 바탕으로 다시 클린코드를 읽어보자. 아래 내용은 지극히 개인적인 관점에서 정리해 본 것으로 아직 부족한 부분이 있을 수 있다.

다시 읽어본 클린코드

1장 깨끗한 코드

코드가 사라질 가망은 없다. ...기계가 실행할 정도로 상세하게 요구사항을 명시하는 작업, 바로 이것이 프로그래밍이다. (2p)

  • 그렇다. ChatGPT 시대에도 누군가는 요구사항을 직접 입력해야 한다.

회사가 망한 원인은 바로 나쁜 코드 탓이었다. (4p)

  • 이것이 바로 좋은 코드를 짜야하는 이유라고 생각한다. 우리가 코드를 짜서 프로그램을 만드는 이유는 장인정신을 발휘하기 위함이 아닌 비즈니스를 위해서다.

결론적으로 1장에선 깨끗한 코드에 대한 여러 사람들의 정의와 그 필요성에 대해 이야기 하고있다. 그러나 정확하게 '클린코드'가 무엇인지는 한 줄로 말해주지는 않는다. 그러나 나쁜 코드에 대해서는 아주 정확하게 이야기 하고 있다. 나쁜 코드는 결과적으로 회사를 망하게 하는 코드이다. 그렇다면 여기서 나아가 반대로 한 줄을 추가해 볼 수 있겠다. 좋은 코드는 회사를 살린다(고 믿고싶다).

2장 의미 있는 이름

의도를 분명히 밝혀라 (22p)

  • 의도가 분명한 이름의 필요성은 200% 공감한다. 변수의 선언에 이름을 붙이는 이유는 본질적으로 의도를 나타내기 위함이다. 책은 여기서 나아가 '함축성'에 대해 강조한다. 좋은 이름은 그 이름을 짓기 위해 고민했던 시간보더 훨씬 더 많은 시간을 절약하게 해준다.

의미 있는 맥락을 추가하라 (35p)
불필요한 맥락을 없애라 (37p)

  • 프론트엔드 개발에선 컴포넌트명으로 사용되는 맥락을 표현하면 내부에서만 사용되는 변수는 다시 이름에서 맥락을 나타낼 필요는 없지 않을까라는 생각이 들었다. 예를 들어 Map.tsx 리액트 컴포넌트 안에서 사용되는 center라는 변수는 mapCenter와 같이 쓰지 않아도 지도의 중앙을 나타낸다는 것을 알 수 있을 것이다.
  • 그러나 전역상태와 관련된 변수명의 경우 중복 회피를 위해 어쩔 수 없이 사용 맥락을 붙이기 시작하면서 변수명이 매우 길어지는 경험을 했던 적이 있다. 이런 경우 근본적인 해결책은 결국 전역에서 사용되는 무언가를 줄이는 것 아닐까?
  • 결국 맥락(Context)이라는 것은 일상 대화에서나 코드에서나 모두 중요하다.

의미 있는 이름 챕터는 사실 굉장히 상식적인 내용들이었다. 개인적으로 마지막 글이 인상적이었다.

좋은 이름을 선택하는 능력은 기술, 비즈니스, 관리 문제가 아니라 교육 문제다. (38p)

이름 짓기는 작업자의 기본적인 교육 수준과 연관되어있다. 기술 문제가 아니라는 부분이 특히 공감되었다.

3장 함수

작게 만들어라 (42p)

  • 보통 함수를 만들거나 리팩토링을 하면 가장 쉽지 않은것이 바로 함수를 작게 만드는 것이다.
  • 함수를 작성하는 과정에서는 코드가 길어질 수 있으나 최종적으로는 전부 작게 분할되어야 한다.
  • 그런데 작다는 것 만으로 함수가 좋다고 말할 수 있는가? 아래 조건을 함께 만족해야 한다.

한 가지만 해라 (44p)

  • 함수는 작으면서 한 가지만 해야 한다. 사이드이펙트도 일으키면 안된다.
  • 하지만 실제로 코드를 짜다 보면 함수는 한 가지 이상 일을 하게된다. 대표적인 예가 바로 명령과 조회를 동시에 해서 그 결과를 사용하려는 코드로 이런 시도는 결국 혼란을 초래한다.
  • 또 하나의 지키기 어려운 케이스가 바로 switch문이다. 기본적으로 switch문은 N가지 일을 한다. 책은 다형성을 이용한 추상 팩토리로 switch문을 감싸는 것을 제안한다.

...의미있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다. (45p)

  • 이 부분은 앞으로도 함수 분리의 지침으로 사용할 예정이다. 다른 함수를 추출할 수 있다면 함수는 아직 완벽하게 분리되지 않았다!

함수가 확실히 '한 가지' 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다. (45p)

  • 어려운 말이지만 생각보다 어렵지 않은 내용이다. 추상화 수준이라는 말은 내부에서 사용되는 코드가 구체적인 동작에 관한 것인지, 아니면 개념적인 내용인지를 나타낸다. 만약 추상화 수준이 높은 코드가 낮은 코드와 뒤섞인다면 세부사항을 추가하기 시작하면서 점차 해석이 어려워질 것이다.

함수에서 이상적인 인수 개수는 0개다. 다음은 1개고, 다음은 2개다. 3개는 가능한 피하는 편이 좋다. 4개 이상은 특별한 이유가 필요하다. 특별한 이유가 있어도 사용하면 안 된다. (50p)

  • 이 부분도 실제 코드를 작성하면 지키기 어려운 부분이다. React 컴포넌트의 경우도 함수이지만 인자로 받는 props는 보통 2-3개 이상인 경우가 많다. 그렇다면 이런 경우는 클린코드가 아닌걸까?
  • 더 이상한 케이스는 바로 플래그다. 책에서는 절대로 bool 값을 함수로 넘기지 말라고 한다. 왜냐하면 이런 경우 함수가 여러 가지 일을 한다고 대놓고 말하는 셈이기 때문이다. 실로 맞는 말이지만 리액트 컴포넌트에서 boolen 값을 props로 넘기는 경우는 종종 발생한다.
  • 이 부분은 의도를 깊이 이해해야 한다. 저자는 인수가 늘어나면 무조건 나쁘다라기 보다는 가독성이 떨어지고 테스트 해야 할 경우의 수가 늘어나는 것을 경계하고있다.
  • 대상 함수가 UI 렌더를 위한 컴포넌트라고 해도 위 내용은 동일하게 적용해 볼 수 있다. 특정 상황에서만 작동하는 boolean값을 props로 넘기기 이전에 상황별로 다른 두 컴포넌트를 만들 수도 있다(혹은 컴포넌트 렌더링 시점에 분기처리를 하거나). 결국 함수 내부에서 boolen을 이용한 분기처리가 많아지면 결과적으로 코드는 복잡해지고 예측 가능성은 떨어지게 된다는 사실은 경험상 맞는 것 같다.
  • 또한 컴포넌트에 전달되는 prop의 수 자체가 지나치게 많아지는 경우 컴포넌트(혹은 함수) 분리의 신호로 생각해 볼 수 있다.

4장 주석

나쁜 코드에 주석을 달지 마라. 새로 짜라. (68p)

  • 클린코드는 주석에 대해 부정적인 것으로 유명하다. 그 이유 중 하나는 바로 주석이 코드와 매칭되지 않는 경우가 자주 발생하기 때문이다. 코드는 진화하지만 주석은 유지보수되지 않는다. 그러나 필요한 경우에 잘 사용된 주석은 긍정적인 역할을 하기도 한다.
  • 주석의 또 다른 문제 중 하나는 주석 자체가 이미 코드 품질이 나쁘다는 증거가 된다는 점이다. 코드에서 의도가 드러난다면 주석은 불필요하다.

좋은 주석 (70p)

  • 법적인 주석
  • 정보를 제공하는 주석
  • 의도를 설명하는 주석
  • 의미를 명료하게 밝히는 주석
  • 결과를 경고하는 주석
  • TODO
  • 중요성을 강조하는 주석
  • API의 JavaDocs(TSDoc)
  • 위 사례에 해당하지 않는다면 책은 모두 나쁜 주석이라고 말한다. TODO나 API의 경우 100% 필요성에 동의한다. 나머지 항목은 github 등에 commit message로 기록하거나 PR에 기록하는 것도 나쁘지 않을 것 같다.
  • 특정 코드 자체가 추후 사용을 위해 주석으로 처리되어 있다면 반드시 지워야 한다고 생각한다. Git의 용도를 다시 생각해보자.

함수나 변수로 표현할 수 있다면 주석을 달지 마라

  • '무슨 동작을 하는 함수'와 같은 주석은 이미 작성한 함수가 무슨 일을 하는지 모르겠다고 스스로 고백하는 최악의 주석이라고 생각한다.

결국 주석도 협업과 커뮤니케이션의 문제라고 생각된다. 생각해보면 코드는 그 자체로 언어이다. 주석의 역할이 언어의 반복이 아닌 필요한 정보가 되기 위해서는 어떤 식으로 작성해야 할지 다시 한번 생각해보게 되었다.

다음 장에서 이어가겠습니다.

0개의 댓글