📘 13.2.3 복잡한 코드를 정리하는 방법 - 함수를 나누어서 깔끔하게 만들기
엉킨 실타래를 풀어내는 마음으로
안녕하세요, 여러분. 지난 시간에 콜백 지옥이라는 복잡한 문제를 만났었죠? 마치 엉킨 실타래처럼 복잡했던 코드들 말이에요. 그 복잡함 속에서 길을 잃기 쉬웠던 우리의 마음을 기억하시나요?
오늘은 그 복잡한 코드를 깔끔하고 이해하기 쉽게 바꿔주는 좋은 방법을 배워볼 거예요. 바로 함수 나누기예요. 마치 큰 레고 덩어리를 작은 조각들로 나누어서 정리하는 것처럼, 또는 무거운 짐을 여러 개의 가벼운 짐으로 나누어 들기 쉽게 만드는 것처럼 말이에요.
🧠 새로운 단어들과 친해지기
단어 | 의미 |
---|---|
함수 나누기 | 큰 함수를 작은 함수 여러 개로 나누어서 정리하는 방법이에요 |
이름 있는 함수 | 무슨 일을 하는지 이름만 봐도 알 수 있는 함수예요 |
모듈화 | 큰 프로그램을 작고 관리하기 쉬운 조각들로 나누는 것을 말해요 |
✨ 함수 나누기가 뭔지 알아보기
여러분이 방 청소를 한다고 생각해보세요. 한 번에 모든 것을 다 정리하려고 하면 너무 복잡해서 어디서부터 시작해야 할지 막막하죠?
하지만 "책상 정리하기", "옷장 정리하기", "바닥 청소하기"처럼 작은 일들로 나누어서 하나씩 해결하면 훨씬 쉽고 마음도 편해져요. 함수 나누기도 정확히 이와 같은 마음에서 시작되어요.
코딩에서도 마찬가지예요. 하나의 함수에 너무 많은 일을 시키면 문제가 생겨요. 대신 "한 함수는 한 가지 일만 하게 하자"는 따뜻한 규칙을 사용해요.
피자 가게의 똑똑한 분업 이야기
함수 나누기를 이해하기 위해 하나의 이야기를 들려드릴게요.
옛날에 "슈퍼 피자" 가게가 있었어요. 처음에는 사장님 혼자서 모든 일을 했어요. 주문받기, 도우 만들기, 토핑 올리기, 굽기, 포장하기, 배달하기까지 정말 모든 것을 혼자 했어요.
그런데 이렇게 하니까 사장님은 너무 바빠서 실수가 자주 생겼어요. 도우를 만드는 중에 전화가 와서 주문을 받고, 그 사이에 오븐에서 피자가 타버리고... 정말 지칠대로 지쳤어요.
그래서 사장님은 현명한 방법을 생각해냈어요. "주문 담당자", "도우 전문가", "토핑 아티스트", "오븐 마스터", "포장 전문가", "배달 기사"로 역할을 나눈 거예요.
이렇게 바뀌고 나서 어떤 일이 일어났을까요?
- 각자 전문 분야에 집중할 수 있게 되었어요
- 문제를 빠르게 해결할 수 있게 되었어요
- 새로운 직원을 가르치기도 쉬워졌어요
결국 "슈퍼 피자" 가게는 동네에서 가장 맛있고 빠른 피자 가게가 되었답니다!
🎯 왜 함수를 나누어야 할까요?
- 코드 읽기가 훨씬 쉬워져요: 함수 이름만 봐도 무슨 일을 하는지 바로 알 수 있어요
- 문제를 찾아서 고치기가 쉬워져요: 어느 함수에서 잘못되었는지 빠르게 찾을 수 있어요
- 같은 코드를 여러 번 사용할 수 있어요: 잘 만든 함수는 다른 곳에서도 다시 사용할 수 있어요
- 함께 일하기가 좋아져요: 여러 명이 함께 코딩할 때 각자 다른 함수를 맡아서 작업할 수 있어요
⚙️ 함수 나누기 방법 배우기
복잡한 코드 (Before):
// 이렇게 모든 것이 하나로 뭉쳐있으면 복잡해요
setTimeout(() => {
console.log("1단계");
setTimeout(() => {
console.log("2단계");
setTimeout(() => {
console.log("3단계");
console.log("완료!");
}, 1000);
}, 1000);
}, 1000);
깔끔하게 나눈 코드 (After):
// 각 단계를 명확한 함수로 나누어 놨어요
function finishWork() {
setTimeout(() => {
console.log("3단계");
console.log("완료!");
}, 1000);
}
function doSecondStep() {
setTimeout(() => {
console.log("2단계");
finishWork();
}, 1000);
}
function doFirstStep() {
setTimeout(() => {
console.log("1단계");
doSecondStep();
}, 1000);
}
// 전체 과정 시작하기
doFirstStep();
이렇게 나누니까 각 함수가 무슨 일을 하는지 이름만 봐도 알 수 있고, 코드를 따라가기도 훨씬 쉬워졌어요!
🧪 직접 해보면서 배우기
🔹 첫 번째 예시: 아침 준비 과정을 단계별로 나누기
// Before: 복잡하게 얽혀있는 아침 준비
setTimeout(() => {
console.log("🔔 알람이 울려요!");
setTimeout(() => {
console.log("😴 세수해요");
setTimeout(() => {
console.log("👕 옷을 입어요");
setTimeout(() => {
console.log("🍞 아침을 먹어요");
console.log("🚌 학교에 가요!");
}, 1000);
}, 1000);
}, 1000);
}, 1000);
// After: 각 단계를 명확한 함수로 나누어서 정리했어요
function goToSchool() {
setTimeout(() => {
console.log("🍞 아침을 먹어요");
console.log("🚌 학교에 가요!");
}, 1000);
}
function getDressed() {
setTimeout(() => {
console.log("👕 옷을 입어요");
goToSchool();
}, 1000);
}
function washFace() {
setTimeout(() => {
console.log("😴 세수해요");
getDressed();
}, 1000);
}
function wakeUp() {
setTimeout(() => {
console.log("🔔 알람이 울려요!");
washFace();
}, 1000);
}
// 아침 준비 시작!
wakeUp();
🔹 두 번째 예시: 게임에서 레벨업 과정 나누기
// 각 단계가 무슨 일을 하는지 이름만 봐도 바로 알 수 있어요!
function showAnimation() {
setTimeout(() => {
console.log("🎉 레벨업 애니메이션!");
console.log("✨ 반짝반짝!");
console.log("게임을 저장했어요");
}, 1000);
}
function giveReward() {
setTimeout(() => {
console.log("🎁 레벨업 보상!");
console.log("⚔️ 새로운 무기를 얻었어요!");
console.log("💎 보석 10개를 받았어요!");
showAnimation();
}, 1000);
}
function updateStats() {
setTimeout(() => {
console.log("📊 능력치 올리는 중...");
console.log("💪 힘: 50 → 55");
console.log("🧠 지능: 30 → 35");
giveReward();
}, 1000);
}
function checkExperience() {
setTimeout(() => {
console.log("⭐ 경험치 확인 중...");
console.log("📈 레벨업 가능해요!");
updateStats();
}, 1000);
}
// 레벨업 과정 시작!
checkExperience();
🔹 세 번째 예시: 온라인 쇼핑몰에서 주문하기 과정
// 실제 쇼핑몰에서 일어나는 과정들을 단계별로 나누어서 만들었어요
function sendEmail() {
setTimeout(() => {
console.log("📧 주문 완료 이메일 발송");
console.log("✅ 주문이 완료되었어요!");
console.log("🎉 쇼핑해주셔서 감사합니다!");
}, 1000);
}
function processPayment() {
setTimeout(() => {
console.log("💳 결제 처리 중...");
let success = Math.random() > 0.2; // 80% 성공률
if (success) {
console.log("✅ 결제 완료!");
sendEmail();
} else {
console.log("❌ 결제 실패. 다시 시도해주세요");
}
}, 1000);
}
function checkStock() {
setTimeout(() => {
console.log("📦 재고 확인 중...");
let inStock = Math.random() > 0.1; // 90% 재고 있음
if (inStock) {
console.log("✅ 재고 충분!");
processPayment();
} else {
console.log("😢 상품이 품절되었어요");
}
}, 1000);
}
function validateUser() {
setTimeout(() => {
console.log("👤 사용자 정보 확인 중...");
console.log("✅ 정보가 올바르게 입력되었어요!");
checkStock();
}, 1000);
}
// 온라인 쇼핑 주문 과정 시작!
console.log("🛒 온라인 쇼핑 주문을 시작해요!");
validateUser();
🔄 함수 나누기 과정 정리하기
- 문제 찾기: 코드에서 복잡하고 이해하기 어려운 부분을 찾아내요
- 단계 나누기: 전체 작업을 의미 있는 작은 단위로 구분해요
- 함수로 만들기: 나누어진 각 단계를 독립적인 함수로 만들어요
- 좋은 이름 붙이기: 함수가 하는 일을 정확히 표현하는 이름을 지어줘요
- 함수들 연결하기: 적절한 순서로 함수들이 호출되도록 연결해요
🧠 자주 하는 실수와 주의할 점
❌ 실수 1: 함수 이름을 대충 짓기
// 나쁜 예 - 무슨 일을 하는지 알 수 없어요
function func1() {
console.log("사용자 로그인");
}
function doSomething() {
console.log("데이터를 불러와요");
}
// 좋은 예 - 이름만 봐도 무슨 일을 하는지 바로 알 수 있어요
function loginUser() {
console.log("사용자 로그인");
}
function loadUserData() {
console.log("데이터를 불러와요");
}
❌ 실수 2: 하나의 함수에 너무 많은 일 넣기
// 나쁜 예 - 하나의 함수가 너무 많은 일을 해요
function doEverything() {
console.log("로그인 중...");
console.log("데이터 로딩 중...");
console.log("화면 업데이트 중...");
console.log("에러 확인 중...");
}
// 좋은 예 - 각 함수가 하나씩의 명확한 역할을 담당해요
function loginUser() {
console.log("사용자 로그인을 처리해요");
}
function loadData() {
console.log("데이터를 불러와요");
}
function updateScreen() {
console.log("화면을 업데이트해요");
}
✏️ 연습문제로 개념 다지기
천천히, 마치 편지를 쓰듯 정성스럽게 문제를 풀어보세요. 복잡함을 단순함으로 바꾸는 이 과정에서 우리는 프로그래밍의 아름다움을 발견할 수 있을 거예요.
Ex1) 복잡한 아침 준비를 깔끔한 함수들로 나누어보자
// 문제: 이 복잡한 코드를 함수로 나누어보세요
setTimeout(() => {
console.log("⏰ 알람");
setTimeout(() => {
console.log("🚿 샤워");
setTimeout(() => {
console.log("👔 옷 입기");
setTimeout(() => {
console.log("🥪 아침 먹기");
console.log("🎒 출발!");
}, 1000);
}, 1000);
}, 1000);
}, 1000);
// 답: 각 단계를 명확한 함수로 나누었어요
function leaveHome() {
setTimeout(() => {
console.log("🥪 아침 먹기");
console.log("🎒 출발!");
}, 1000);
}
function getDressed() {
setTimeout(() => {
console.log("👔 옷 입기");
leaveHome();
}, 1000);
}
function takeShower() {
setTimeout(() => {
console.log("🚿 샤워");
getDressed();
}, 1000);
}
function wakeUp() {
setTimeout(() => {
console.log("⏰ 알람");
takeShower();
}, 1000);
}
wakeUp();
Ex2) 온라인 게임 로그인 과정을 단계별 함수로 만들어보자
function startGame() {
setTimeout(() => {
console.log("🎮 게임 시작!");
console.log("🌟 즐거운 게임 되세요!");
}, 1000);
}
function loadCharacter() {
setTimeout(() => {
console.log("👤 캐릭터 로딩 중...");
console.log("⚔️ 캐릭터 준비 완료!");
startGame();
}, 1000);
}
function connectServer() {
setTimeout(() => {
console.log("🌐 서버 연결 중...");
console.log("✅ 서버 연결 완료!");
loadCharacter();
}, 1000);
}
function checkPassword() {
setTimeout(() => {
console.log("🔐 비밀번호 확인 중...");
console.log("✅ 비밀번호 맞아요!");
connectServer();
}, 1000);
}
// 게임 로그인 시작!
console.log("🎯 게임 로그인을 시작해요!");
checkPassword();
🤔 조금 더 어려운 문제로 실력 확인하기
Q1. 함수 나누기의 가장 큰 장점은 무엇일까요?
정답: 코드를 읽고 이해하기 쉬워진다는 점이에요.
해설: 각 함수가 하나의 명확한 역할을 하게 되어서, 무슨 일이 어떤 순서로 일어나는지 한눈에 알 수 있어요.
Q2. 다음 중에서 가장 좋은 함수 이름은 무엇일까요?
A) doSomething
B) handleStuff
C) calculateGrade
정답: C) calculateGrade
해설: 함수 이름은 그 함수가 하는 일을 구체적이고 명확하게 설명해야 해요.
🔙 지난 시간 복습하기 (13.2.2 - 콜백 지옥)
복습 문제 1: 콜백 지옥의 특징이 아닌 것은?
A) 코드가 계단 모양으로 들여쓰기됨
B) 함수 안에 함수가 중첩됨
C) 함수 실행 속도가 빨라짐
D) 읽기 어려워짐
정답: C) 함수 실행 속도가 빨라짐
복습 문제 2: 다음 코드가 콜백 지옥인 이유는?
step1(() => {
step2(() => {
step3(() => {
step4(() => {
console.log("완료!");
});
});
});
});
정답: 함수 안에 함수가 4번 중첩되어 있어서 코드가 계단 모양으로 복잡해졌기 때문이에요.
함수 나누기는 복잡한 코드를 이해하기 쉽고 관리하기 쉽게 만드는 중요한 기술이에요. 마치 복잡한 퍼즐을 작은 조각들로 나누어서 하나씩 맞춰가는 것처럼, 코딩에서도 작은 함수들을 잘 만들어서 조립하면 멋진 프로그램을 만들 수 있답니다!
✅ 학습 완료 체크리스트
학습 내용 | 이해했나요? |
---|---|
함수 나누기의 개념 | ✅ |
함수 나누기의 장점 | ✅ |
좋은 함수 이름 짓기 | ✅ |
실전 예제 만들기 | ✅ |
실수 피하는 방법 | ✅ |
🎯 추가 연습 문제들
추가 문제 1. 콜백 지옥을 함수 분리로 해결해보세요
// 문제
setTimeout(() => {
console.log("요리 시작");
setTimeout(() => {
console.log("재료 준비");
setTimeout(() => {
console.log("요리 완성");
}, 1000);
}, 1000);
}, 1000);
// 답
function finishCooking() {
setTimeout(() => console.log("요리 완성"), 1000);
}
function prepareIngredients() {
setTimeout(() => {
console.log("재료 준비");
finishCooking();
}, 1000);
}
function startCooking() {
setTimeout(() => {
console.log("요리 시작");
prepareIngredients();
}, 1000);
}
startCooking();
추가 문제 2. 함수 이름을 더 명확하게 바꿔보세요
// 문제
function doStep1() { console.log("사용자 로그인"); }
function doStep2() { console.log("데이터 불러오기"); }
// 답
function loginUser() { console.log("사용자 로그인"); }
function loadData() { console.log("데이터 불러오기"); }
📂 마무리 정보
오늘 배운 함수 나누기가 여러분의 자바스크립트 지식에 잘 저장되었나요? 다음 시간에는 더 현대적인 해결 방법인 Promise에 대해 배워볼 예정이에요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
'13. 시간을 다루는 마법 (비동기 처리) > 13.2 콜백 함수와 콜백 지옥' 카테고리의 다른 글
13.2.2 콜백 지옥 문제점 - 끝없는 미로 같은 코드들 (0) | 2025.07.18 |
---|---|
13.2.1 콜백 함수란? - 다른 함수에게 맡기는 특별한 임무 (0) | 2025.07.18 |