sungyup's.

becoming_a_better_programmer / you.write(code); / 1.3 코드 적게 쓰기

1.3코드 적게 쓰기

적은 코드가 더 나은 소프트웨어를 만든다. 삭제는 종종 최고의 개선이다.

TL;DR

많은 양의 코드 작성이 좋은 소프트웨어 개발을 의미하지 않는다. 많은 코드들은 오히려 전체 개발량에 부정적 영향을 미쳐, 마치 반물질(antimatter, 물질을 만나면 같이 소멸해버리는 물질)과 같다.

소프트웨어를 개선하는 최고의 방법 가운데 하나는 코드를 제거하는 것이다.
p.50

코드에 신경 써야 하는 이유

  • 새로운 코드 작성은 작은 생명체의 탄생이다. 이 코드가 소프트웨어 사회의 유용하면서도 수익성 높은 구성원이 될 수 있도록 애정으로 키워야한다.
  • 코드들은 유지보수되어야 하고, 각 줄의 코드마다 비용이 든다.
  • 수많은 코드란 읽고 이해해야할 내용이 많음을 의미하고, 프로그램을 파악하기 더 어렵게 한다.
  • 코드가 많아질수록 프로그램을 수정하기 어려워진다.
  • 코드는 버그를 품고 있어, 코드가 많을수록 버그가 숨을 곳이 많다.
  • 중복 코드는 치명적이다. 한군데 버그를 고쳐도 30군데 다른 곳의 버그는 남아있을 수 있다.

허술한 논리

조건문과 중복적 논리 구조의 남발을 조심해야 한다.

javascript
if(boolean){ return true; } else { return false; }

이 코드는 그냥 아래와 같이 표현 가능하다:

javascript
return boolean;

조건문을 잘 이해하고 명백하고 간결하게 사용하자.

리팩토링

리팩토링은 2012년, Martin Fowler의 책인 Refactoring을 통해 유명해진 용어(등장은 1990년대)다. 이 용어는 결과의 변경 없이 기존 코드의 구조를 재조정하는 것이다.

그런데, 종종 결과의 변경 없이 부분이 잊히곤 한다. 프로그램의 작동 방식도 바뀐다면 이는 개선이다. UI 조정 또한 정돈(tidy-up)이다.

리팩토링은 코드 가독성을 높이고, 내부 구조를 향상하고, 유지 보수를 원활히 하여 나중에 있을 기능 개선에 대비하려는 것이다.

중복

코드를 복사한다는 것은 존재한다는 버그는 모두 복사하되 반복 구조는 숨긴다는 뜻이다.
p.54

우리는 불필요한 중복이 없는 DRY(Don't Repeat Yourself) 코드 작성을 목표로 한다. 다만, 불필요하게 공통 함수로 무작정 합쳐 결합도가 지나친 코드 유연성을 해칠 수 있다. 기능이 분리되어야 하는 경우엔 오히려 개별 구현이 나을 수도 있다.

죽은 코드

죽은 코드란, 실행되거나 호출되지 않는 코드다. 예를 들면 절대 충족되지 않는 조건에 들어있는 코드 등이다.

주석

좋은 코드는 작동법을 설명하는 대량의 주석을 필요로 하지 않는다.
p.59

코드는 그 자체로 무엇을 하고 어떻게 작동하는지 나타낸다. 주석은 이유를 설명하는 용도로 쓰자.

복잡한 코드베이스에선 주석처리로 삭제된 '이전' 코드를 보는 경우가 많다. 절대 하지 마라. 이건 완벽히 코딩할 자신이 없는 개발자나 자신이 무엇을 하고 있는지 이해하지 못했거나 나중에 다시 롤백해야 한다고 생각한 사람이 남긴 표식이다. 코드를 완벽히 제거하라. 언제든 소스 관리 시스템을 통해 복원할 수 있다.

코드가 어떤 역할을 하는지 설명하는 주석을 달지 마라.

장황한 내용

삼항 연산자(Ternary operator)를 적극 활용해 코드를 줄여라.

그래서 무엇을 해야할까

불쾌한 코드는 대부분 고의적으로 작성된건 아니다. 대신, 책임감을 가지고 공백을 개선하고 어지러운 코드를 줄이고 균형을 유지해야 한다.

단, 여기서 주의해야할 것은 정돈(tidying up)은 다른 기능적 변화와는 별개로 전개해야 한다. 그래야만 소스 관리 시스템에서 무슨 일이 일어났는지를 명확히 이해할 수 있다.


🥸 생각해보기

1. 간결한 논리적 표현을 사용하는가? 간결한 표현이 너무 간결하여 이해하기 어렵지는 않은가?

간결한 표현을 쓰려고 노력하지만, 동료의 간결한 표현을 보고 잘 이해 못한 적이 개인적으로 몇번 있었다. 이럴 때 나는 쓸 때 풀어서 썼던것 같은데(특히 조건문 등) 지금 생각하면 개인적인 공부가 부족했던것 같다.

하지만 한편으론 '간결함'보단 '이해하기 쉬운' 코드가 우선되어야 한다고 생각해, 썼던 코드들이 아주 나쁘다고 생각하진 않는다. 중요한건 균형 감각일 것이다. 간결하면서도 이해가 잘 되는 적절한 균형을 찾아야할 것이다.

2. 삼항 연산자, 예를 들면 조건 ? 참 : 거짓과 같은 읽기 쉽게 만드는가, 아니면 어렵게 만드는가? 이유는?

개인적인 경험으로 단순한 경우는 아주 좋았다. 말 그대로 조건 ? 참 : 거짓 문법은 쓰기도 편하고 읽기도 쉽다.

다만 쓰다보면 붙이고 붙여 조건1 ? 조건 2 ? 참 : 거짓 : 참 : 조건 3? ...와 같은 극악의 경우가 될 때도 있었다. Tailwindcss로 스타일링하다보면 ${isSelected ? isToday ? bg-blue-500 : ...}와 같은 경우가 있었는데, 아주 읽기 불편하고 수정도 어려웠다.

3. 잘라내기&붙여내기 코딩은 피해야 한다. 공통 함수로 코드 일부를 나눌때의 기준은 어느 정도가 적당한가?

명확히 역할이 같을때만 공통 함수로 합쳐야한다고 생각한다. 비슷하게 생겼다고 서로 다른 곳에 쓰이는 컴포넌트를 묶었다가 나중에 너무 그 컴포넌트 자체에 묶여버린 적이 있다.

4. 죽은 코드를 어떻게 발견하고 제거할 수 있는가?

잘 모르겠어서 검색해보니 죽은 코드를 발견하는 방법은 여러 가지가 있다.

  1. IDE 도움 받기: 대부분의 IDE는 사용되지 않는 변수, 함수, import 등을 회색으로 표시해준다. 이런 표시들을 주의 깊게 보고 제거하는 습관이 중요하다.
  2. Linting 도구 활용: ESLint 등의 정적 분석 도구는 사용되지 않는 코드를 감지해준다. 규칙을 설정하면 자동으로 경고받을 수 있다.
  3. 테스트와 커버리지 분석: 코드 커버리지 도구(예: Istanbul, Vitest Coverage)를 통해 어떤 코드가 전혀 실행되지 않았는지를 확인할 수 있다.
  4. 리팩토링 시기: 기능 추가나 수정 중 코드 흐름을 다시 검토하면서, 호출되지 않는 함수나 조건문을 발견했을 때 과감하게 제거하는 것도 좋은 방법이다.

5. 몇몇 코딩 표준은 모든 함수를 특별히 정형화된 주석으로 문서화하도록 한다. 이것은 유용한가? 아니면 불필요한 여분 주석으로 짐이 될까?

개인적으로는 유용하다고 생각한다. 특히나 프로젝트가 커지고 매개변수가 너무 많을때, 한번 주석을 읽고 접근하는 것이 편했다.

JavaScript 논리 연산자 정리