좋은 코드에 대한 생각 정리
고민
항상 개발하면서 생각하는 공통사항이다.
지금보다 깨끗하고 더 나은코드를 작성하고 싶다.
...
그래서 더 나은코드가 뭔데?
결국 매번 답을 내리지 못한채 코딩을 이어갔고 조금 더 정성들여 코드를 작성해왔다.
이젠 이글을 통해서 내 생각을 정리하고 꾸준히 생각나는대로 업데이트 해보려고 한다.
균형있는 개발코드
사실 좋은코드, 나은코드라는 것이 정답이 있지는 않다.
누군가는 짧고 구동 속도가 빠른코드라면 좋다고 느낄 것이고
누군가는 주석이 잘 달려있다면 좋다고 느낄 것이고
누군가는 버그가 없다면 좋다고 느낄 수 있다.
내 생각은 다음과 같다.
- 읽기 쉽고, 유지보수가 용이한가?
- 사용자 편의를 고려했는가?
- 확장이나 업데이트를 고려했는가?
- 안정적이며 예외상황을 최소화 했는가?
이제 하나씩 내용을 정리해보자.
읽기 쉽고 유지보수가 용이한 코드
개인적으로 주석을 자주 달지 않는다.
복잡하거나 전달하고자 하는 메시지가 꼭 필요할때만 깊은주석으로 적는 편인데
진정 원하는 코드는 주석이 필요없고 읽어보기만 해도 이해가 가능한 코드를 선호한다.
내가 아닌 누군가가 신입, 선임이 유지보수나 기능수정을 하더라도 코드를 해독하는 시간이 짧았으면 한다.
사실 다른이의 코드를 보고 간단한 작업임에도 해독시간이 압도적으로 길었던 경험이 있다.
그 경험으로 인해 오히려 더 신경쓰게 된 것 같다.
또, 줄임말을 극도로 꺼려하는데 남들이 예측가능하도록 변수, 상태(State)를 쓰려고 노력한다.
예를들면 이런 코드와 같다.
// Bad
const val = getData();
// Good
const User = getUserData();
// Bad
list.map((el,i) => {
return {
id: i,
title: el.title,
}
})
// Good
posts.map((post,index) => {
return {
id: index,
title: post.title,
}
})
이처럼 el, i, j, val과 같이 지금 개발중인 사람에게는 이해가 가능하지만
코드를 오랜만에 보거나 처음본 사람에게는 이 변수나 객체가 어디서부터 왔는지 추적해야 할수도 있다.
개발시간에 큰 차이가 없다면 이처럼 el이나 value 대신 명확히 어떤 내용을 담는지 예측 가능하도록 하고 줄임말은 피했으면 한다.
사용자 편의를 고려한 코드
프론트엔드로 일하고 있는 나에게 누군가 해준 말이 있다.
"정책이나 유저경험은 기획, 디자인이 해주는거야"
귀담아 듣지 않았다. 아무리 생각해도 그건 아닌것 같아서다.
결국 기획, 정책, 디자인 모두 우리가 반영하는 부분인데?
그럴거면 GPT를 쓰지.. 아니 GPT가 더 나은 편의성을 제시할 수도 있겠는데..
사용자 편의라는 것이 무엇일까?
우선 사용자는 코드를 보지 않는다.
프로젝트의 의도를 거부감 없이 전달하고 유저의 필요없는 액션을 최소화하는 것
예를들면 사용자가 일부 데이터를 조회나 처리할때 다른 액션을 막는 행위 같은 것
우리가 Loading Indicator나 Alert을 표현할때 무작정 반투명 Background로 처리하기 보다는
해당 구역의 Loading을 표현해주거나 SnackBar 형태의 알림만 표시해주는 고려도 필요할 수 있다.
기간제 결제 서비스 또한 유저에게 자동결제를 묻는 형태를 고려해볼 수 있겠다.
유저가 굳이 매일, 매주, 매월 결제할 필요가 없다면 말이다.
이 처럼 더 나은 방향이 있다면 회의를 통해서 의견제시가 필요하다.
확장성이나 업데이트를 고려한 코드
아키텍쳐, 설계 등 여러 요소들이 곂치는 포인트다.
웹 프론트엔드 작업에는 언어, 프레임워크 그리고 수 많은 라이브러리가 필요하다.
이를 선정하는 것에 있어 빠질 수 없는 요소들이 존재하는데
바로 버전, 업데이트, 사용자, 라이브러리 평가를 충분히 봐야한다.
다음과 같은 상황이라면 어떤 선택을 하겠는가?
(2025/04/14 기준)
moment.js
- 업데이트 : 2024년 12월 (최근 업데이트)
- 사용자 : 주당 약 1,400만 다운로드 (2025년 4월 기준)
- 평가 : 기능 풍부하나 무거움, 신규 프로젝트 비추천
dayjs
- 업데이트 : 2025년 3월 (최근 업데이트)
- 사용자 : 주당 약 2,400만 다운로드 (2025년 4월 기준)
- 평가 : 가볍고 현대적, 성능 호평
이렇게 간단하게만 정리해도 dayjs가 더 나은 선택으로 보인다.
moment는 가변성설계, 번들크기 등등 여러 이유로 공식 deprecated 상태인 것도 생각해야한다.
시작이 반이다 라는 말처럼 설계, 라이브러리나 프레임워크 선정을 우습게 봐선 안된다.
디렉토리 구조나 전체적인 아키텍쳐 설계는 첫번째 고민요소인 유지보수, 가독성과도 연관이 크다.
예외상황을 고려하며 안정적인 코드
예외상황을 고려하는 코드는 사용자 경험과 직결되며 동시에 시스템의 신뢰성을 높이는 핵심 요소다.
아무리 가독성이 좋고, 확장성이 뛰어난 코드를 작성했더라도 예외 상황에서 무너진다면
결국 사용자에게 불편함을 주거나 신뢰를 잃게 된다.
프론트엔드 개발자로서, 사용자가 예상치 못한 상황에서도 자연스럽게 서비스를 이용할 수 있도록 하는 것이 중요하다고 생각한다.
내가 추구하는 안정적인 코드는 다음과 같은 점을 고려한다.
첫째, 가능한 모든 에러를 예측하고 처리한다.
API 호출이 실패하거나, 데이터가 예상과 다르게 들어올 때 혹은 사용자가 비정상적인 입력을 할 때 어떻게 반응할 것인가?
이런 상황을 미리 생각하고 대비해야 한다.
예시로 API 응답 타입을 명확히 정의하고, 예상치 못한 데이터가 들어오더라도 안전하게 처리할 수 있도록 코드를 작성한다.
// Bad
const getUser = async () => {
const response = await fetch('/api/user');
const user = await response.json();
return user.name;
};
// Good
const getUser = async () => {
try {
const response = await fetch('/api/user');
if (!response.ok) {
throw new Error('Failed to fetch user');
}
const user = await response.json();
return user.name || null;
} catch (error) {
console.error('Error fetching user:', error);
return null;
}
};
급하게 작성한 코드를 보면 간혹 이미 API는 실패했으나 화면은 Loading뿐이고 다른 액션을 취하지 못하는 상황도 보인다.
이 처럼 실패를 부드럽게 넘어가거나 사용자에게 자연스럽게 알려야 한다.
그게 바로 두번째 요소인데
// Bad
const UserProfile = ({ user }) => {
if (!user) return `<div>Error: User not found</div>`;
return `<div>${user}</div>`;
};
// Good
const UserProfile = ({ user }) => {
if (!user) return `
<div>
<p>사용자 정보를 불러오지 못했습니다.</p>
<button onClick={action}>
다시 시도
</button>
</div>
`;
return `<div>${user}</div>`;
};
위 사례처럼 유저에게 Error: User not fount는 아주 불친절한 개발문장 일 수 있다.
물론 읽어보면 이해할 수는 있지만 그 사람에게 맞는 언어를 사용하거나 재처리의 여지도 남겨놓을 수 있겠다.
내용들을 정리하면서 드는 생각이 많다.
가끔은 시간에 쫒겨 넘어가는 내 자신을 돌아보게 된다.
앞으로 생각나는 좋은 코드에 대해 이 글에 꾸준히 업데이트 해야겠다.
(2025/04/14 최초작성)