읽기 좋은 코드의 기본 조건

Dada·2023년 9월 9일
0

Dev log

목록 보기
1/9

좋은 코드의 시작은 좋은 가독성이다.

가독성이 좋은 코드에 대해 고민했던 내용을 정리해보려한다.

변수명

모던 자바스크립트 딥다이브에 보면 아래와같은 구절을 확인할 수 있다.

변수 이름은 첫아이 이름을 짓듯이 심사숙고해서 지어야 한다.

주석이나 구두의 설명 없이도 이해하기 쉬운 변수명으로, 함수명으로, 컴포넌트명 만으로도 팀원에게 설명이 되는 것이 좋은 변수명이라고 할 수 있다.
딥다이브를 읽으며 위의 문장이 가장 기억에 남았던 구절인 만큼 나는 개발을 할 때 변수명 짓는 것 하나는 꽤나 신경쓴다고 생각했다. 그러다 문득문득 과연 제대로 하고있나 라는 의문이 들곤 했다.

내 변수명이 별로라고 느낄 때, 그 이유를 생각해 보았다.

  • 습관이 생각을 넘어섰다.
  • 한 페이지 안에, 한 컴포넌트 안에 코드들이 쌓이면서 식별자들이 가진 의미가 모호해지기 시작했다.
  • 나름 고심해서 지었다 생각했는데 나한테만 명확한 네이밍이었다.

내 코드를 보며 동료가 식별자 명만으로 한 번에 역할을 이해하지 못하고 할당된 혹은 함수 내부의 로직을 보는 시간이 굉-장히 오래 걸린다면 그것은 위 세 가지 이유로 무언가 잘못 된 식별자 명일 것이리라.

const [isShowModal, setIsShowModal] = useState(false)

작은 범위의 컴포넌트에 모달이 하나가 있다고 가정했을 때는 위와 같은 상태명이 그리 큰 문제가 되지 않을 수도 있다. 모달을 닫고 끄는 상태는 저것 하나로 충분할 테니 말이다.

그런데 아래와같은 동작이 있다고 가정해보자.

페이지에 매장을 찾는 버튼이 있다.
-> 특정 매장을 찾는 모달이 뜬다.(매장 모달)
-> 모달에서 주소를 클릭하면 지도 모달이 뜬다.(지도 모달)
-> 지도 모달을 끄고 다시 매장 찾는 모달에서 특정 매장을 선택하여 확인을 누르면 비회원의 경우 로그인 모달이 뜬다.(로그인 모달)

그런데 위와같은 상황에서는 한 시나리오 안에 세 개의 모달의 동작이 있다. 이 때 생각없이 첫번째 스텝인 '매장 모달'을 개발하는 과정에서 'isShowModal'과 같은 상태명을 사용하면 어떻게 될까?
당연하게도 혼란을 야기한다.
공통으로 쓰이는 컴포넌트도 아닐테고 나만 쓰는데 나만 알아보면 되지 않겠어? 라는 생각은추후 수습하기 어려운 코드로 전락한다. 개발이 되어가며 수많은 컴포넌트가 생기고 -> 작성해 놨던 코드와 시간의 갭이 생겨 잊혀질 즈음 여러가지 이유로 다시 돌아봤을 때 나도 헷갈리는 치명적인 코드가 되어 화살은 나에게 돌아온다.
엎친데 덮친격으로 나만 쓰려고 만든 컴포넌트가 공통컴포넌트가 되어야하는 상황은 생각보다 빈번하게 일어나며 게으름의 결과로 수습 작업에 꽤나 많은 시간을 쏟아야 한다.

이해하지 못할 바엔 장황한 게 낫다

나는 사실 장황한 것을 별로 좋게 생각하지 않았다. 그런데 개발을 하다보면 하나의 이름 안에 그 안에 담긴 모든 기능들에 맞는 하나의 단어로 선택해 만드는 게 그리 쉬운 일이 아니란 걸 매번 느끼곤 한다. 예를 들어 사이즈도 선택하고 색상도 선택하고 선택한 상품의 개수까지 정한 상태에서 장바구니에 담을지 바로구매로 보낼지 정해야 하는 로직이 있다고 해보자. 뭔가 하나로 정의내릴 수 있을 것 같은데 쉬이 떠오르지 않는다.

네이버를 예로 들어보자!

상품을 구매하기 위해. 색상과 사이즈, 수량을 선택한 뒤 -> 구매 혹은 찜, 장바구니에 갈지를 정해야 한다.
처음에 이 컴포넌트명을 뭐라고 지어야할까 대충 생각해보면, '구매'라는 키워드와 선택한 상품 리스트가 쌓이니, '리스트'라는 키워드를 생각해 볼 수 있다. 그럼 합쳐서 'PurchaseList'. 과연 좋은 이름일까? purchaseList는 오히려 결제 부분에서 적합할 것이다. 아직 사용자는 구매한다고 결정하지 않았다. 찜만 할 수도 있고 장바구니로만 갈 수도 있는데 'PurchaseList'는 해당 기능들을 모두 담기는 참 애매하다. 좀 더 명확한 이름이 뭐가 있을까?

  • 옵션을 선택한다.
  • 구매 가능성이 있다.
  • 문의를 하거나, 찜하거나, 장바구니로 향한다.

ProductOptionsWidget은 어떨까?
위 세 가지 기능을 함축적으로 생각해보면 사용자의 인터렉션이 있는 동작이기에 관련된 단어를 찾아보았다.

  • Widget
    길지만 PurchaseList보단 명시적인 이름이라고 생각한다.

명시적인 게 좋다

코드에서 명시적이라고 하면 흔히 네이밍을 떠올릴 것 같은데 생각보다 작은 부분에서 헷갈리게 하는 것들이 있다.

const onHandleModal = () => setIsShowModal(prev => !prev);

예로 나는 모달 이벤트가 발생시 이전값을 기반으로 boolean의 상태를 조절해왔는데 코드의 양이 많아질수록 명시성이 떨어진다는 느낌을 받았다.
인자를 사용해 이전값을 기반으로 어떠한 상태를 변경할 때는 유용하지만 단순히 모달을 열고 닫을 때 close에는 false를, 여는 동작에선 true를 사용해주는 것이 훨씬 명시적으로 느껴졌다.
팀원이 코드를 본다면 '어느 상태에서 상태값을 뒤집는거야?'라는 생각이 안 들게 하는 게 포인트다. 팀원이 헷갈리면 훗날의 나도 헷갈린다는 사실을 깨달았다. 아니 머리로는 알고 있었지만 겪어보지 못해 몰랐던 사실을 경험을 통해 느꼈다는 게 맞겠다.
리팩토링을 하면서 prev로 되어있는 것들을 바꾸며 훨씬 가독성이 좋아진 것을 확인할 수 있었다.

물론 컨벤션이 이전 값을 기반으로 boolean 상태를 조절해야 한다면(혹은 상황에 따라) 그게 맞다!

profile
우당탕탕 개발로그

0개의 댓글