아래 내용은 토스ㅣSLASH 21 - 실무에서 바로 쓰는 Frontend Clean Code을 보고 정리한 내용입니다.
TL:DR;
로직에서 핵심 개념을 뽑아서 분리하는 것이 중요하다!
클린 코드 !== 짧은 코드
클린 코드 === 찾고 싶은 로직을 빠르게 찾을 수 있는 코드
지뢰 코드란? 흐름 파악이 어렵고, 도메인 맥락이 표현이 안되어 동료에게 물어봐야 알 수 있는 코드
실무에서 클린 코드의 의의: 유지보수 시간(코드 파악 + 디버깅 + 리뷰)을 단축함으로써 자원을 줄일 수 있다.
기능을 추가할 때, 응집도, 단일책임, 추상화 3가지를 고려해야 한다.
단, 이 때 코드 파악을 할 때 당장 몰라도 되는 디테일은 뭉쳐야 하고 코드 파악에 필수적인 핵심 정보는 뭉쳐선 안된다. 아래 코드에서는 팝업을 조작하는 코드가 흩뿌려져있다. 커스텀 훅을 이용해서 리팩토링 해보도록 하자.
function QuestionPage() {
// 팝업을 조작하는 코드 1
const [popupOpened, setPopupOpened] = useState(false);
async function handleClick() {
setPopupOpend(true);
}
// 팝업을 조작하는 코드 2
function handlePopupSubmit() {
await 질문전송(연결전문가.id);
alert("질문을 전송했습니다.")
}
return (
<>
<button onClick={handleClick}>질문하기</button>
{/* 팝업을 조작하는 코드 3*/}
<Popup title="보험 질문하기" open={popupOpened}>
<div>전문가가 설명드려요</div>
<button onClick={handlePopupSubmit}>확인</button>
</Popup>
</>
);
}
Tip: 핵심 데이터와 세부 구현을 나눈 후 응집한다.
function QuestionPage() {
// 세부 구현은 커스텀 훅으로 빼고
const [openPopup] = usePopup();
async function handelClick() {
// 핵심 데이터는 표시되도록 (제목, 내용, 액션)
const confirmed = await openPopup({
title: "보험 질문하기",
contents: <div>전문가가 설명드려요</div>,
});
// 사용자의 행동을 기다렸다가 확인을 누르면 아래 실행해라
if(confirmed) {
await submitQuestion();
}
}
async function sumbitQuestion(연결전문가) {
await 질문전송(연결전문가.id);
alert("질문을 전송했습니다.");
}
return <button onClick={handleClick}>질문하기</button>;
}
위 코드와 같이 핵심 데이터만 전달받고 세부 구현은 뭉쳐 숨겨 두는 개발 스타일을 선언적 프로그래밍
이라고 한다. 예시 코드는 다음과 같다.
<Popup onSubmit={질문전송} onSuccess={홈으로이동} />
<Popup onSubmit={회원가입} onSuccess={프로필로이동} />
아래와 같은 코드가 있다고 가정하자.
해당 코드에서 기능이 추가되면 더욱 읽기 힘들어질 것이다. 단일책임 원칙을 적용해 함수를 기능별로 나누면 다음과 같이 분리할 수 있다.
추상화란, 개발자가 코드의 세부구현을 필요에 따라 얼마나 숨기느냐를 말한다. 예를들어, 추상화 단계 별로 코드를 나눠본다면 다음과 같다.
Lv.0
<Button onClick={showConfirm}>
전송
</Button>
{isShowConfirm && (
<Confirm onClick={() => {showMessage("성공")}}/>
)}
Lv.1
<ConfirmButton
onConfirm={() => {showMessage("성공")}}
>
전송
</ConfirmButton>
Lv.2
<ConfirmButton message="성공">전송</ConfirmButton>
상황에 따라 필요한만큼 추상화를 하면 되지만, 아래와 같이 추상화 수준이 섞여 있지 않도록 한다!
두려워하지 말고 기존 코드를 수정하자
그 때는 맞고 지금은 틀릴 수 있다. 기능 추가 자체는 클린해도, 전체적으로는 어질러울 수 있다.
당장은 사소한 이슈라고 해도 일관성을 깨는 코드가 쌓이면 유지보수하기 힘든 코드가 된다. 코드에 정답은 없기 때문에, 명시적으로 이야기를 하는 시간이 필요하다.
이 코드가 향후 어떤 점에서 위험할 수 있는지, 어떻게 개선할 수 있는지를 적어보자.