18. 똑똑한 코드 패턴 (디자인 패턴)/18.2 팩토리 패턴

18.2.2 객체 생성 팩토리 만들기 - 똑똑한 제조공장처럼

thejavascript4kids 2025. 7. 27. 06:00

📘 18.2.2 객체 생성 팩토리 만들기 - 똑똑한 제조공장처럼

안녕하세요, 여러분. 이전 시간에 우리는 필요한 것을 주문하면 척척 만들어주는 팩토리 패턴이 무엇인지 알아보았습니다. 마치 숙련된 장인이 다양한 작품을 만들어내는 것처럼, 프로그래밍에서도 우리가 원하는 객체를 자연스럽게 만들어주는 특별한 공장을 만들 수 있다는 것을 배웠죠.

이번 시간에는 그 특별한 공장, 바로 객체 생성 팩토리를 직접 만들어보는 여행을 떠나보겠습니다. 마치 진짜 공장장이 되어서 나만의 제조 라인을 설계하는 것처럼 흥미로울 거예요.

🧠 새로운 용어들과 만나기

코딩의 세계로 들어가기 전에, 우리가 오늘 배울 특별한 용어들과 먼저 친구가 되어보겠습니다.

용어 의미
팩토리 함수 여러 종류의 객체를 만들어주는 특별한 함수로, 마치 공장의 기계처럼 동작해요
공통 속성 만들어지는 모든 객체가 공통으로 갖는 특징이나 정보를 말해요
타입별 기능 각 객체의 종류에 따라 다르게 추가되는 특별한 능력이나 특징이에요
설정 옵션 객체를 만들 때 우리가 원하는 대로 조정할 수 있는 선택 사항들이에요

이 용어들은 우리가 코딩 공장을 만들어 나가는 과정에서 자주 만나게 될 친구들이에요. 하나씩 차근차근 알아가다 보면 어느새 친숙해질 거예요.

✨ 팩토리 만들기의 핵심 개념

객체 생성 팩토리는 마치 숙련된 장인의 작업실과 같습니다. 이 작업실에서는 우리가 "이런 물건을 만들어 주세요"라고 요청하기만 하면, 장인이 알아서 완벽한 작품을 만들어 줍니다.

일반적인 제작 과정과 달리, 우리가 만들 팩토리는 다양한 종류의 객체를 하나의 공장에서 모두 만들 수 있습니다. 마치 도자기 공방에서 컵도 만들고, 접시도 만들고, 화분도 만들 수 있는 것처럼 말이에요. 그런데 신기한 점은 모든 도자기 제품들이 기본적인 흙 빚기 방식은 같다는 것입니다.

팩토리의 가장 큰 장점은 동일한 방식으로 서로 다른 객체를 만들 수 있다는 점입니다. 우리는 복잡한 제조 과정을 알 필요 없이, 그저 "어떤 종류의 객체가 필요한지"만 알려주면 되는 거예요. 공장이 나머지 모든 일을 자연스럽게 처리해 줍니다.

우리 동네 빵집으로 이해하기

팩토리를 더 쉽게 이해하기 위해 '우리 동네 빵집' 이야기를 들려드릴게요.

우리 동네에는 친절한 빵집 사장님이 계세요. 이 빵집의 특별한 점은 한 번에 여러 종류의 빵을 만들 수 있다는 것이었어요. 식빵, 단팥빵, 크림빵뿐만 아니라 케이크나 쿠키 같은 특별한 메뉴까지 만들 수 있었죠.

빵집에서 일하는 사장님은 주문을 받으면 먼저 모든 빵의 기본 재료들을 준비해요. 밀가루, 설탕, 버터 같은 재료들과 깨끗하고, 맛있으며, 영양가 있다는 기본적인 특징들을 갖추는 거죠.

그다음 사장님은 빵의 종류에 따라 특별한 재료와 제조법을 추가해요. 단팥빵이면 달콤한 팥을 넣고, 크림빵이면 부드러운 크림을 넣는 식으로요.

마지막에는 손님들이 원하는 특별한 요청들도 반영할 수 있어요. 덜 달게 해달라거나, 견과류를 더 넣어달라거나, 작게 만들어달라는 요청들 말이에요.

우리가 만들 객체 팩토리도 이 동네 빵집과 똑같이 동작한답니다.

🎯 팩토리를 만드는 이유

그렇다면 우리는 왜 이런 특별한 팩토리를 만들어야 할까요? 여러 가지 좋은 이유들이 있어요.

첫 번째 이유는 같은 일을 반복하지 않기 위해서입니다. 만약 팩토리가 없다면, 비슷한 객체를 만들 때마다 똑같은 코드를 계속 써야 할 거예요. 마치 빵을 만들 때마다 처음부터 밀가루를 체치고, 기본 반죽을 만들고, 오븐을 예열하는 것과 같죠. 팩토리가 있으면 한 번만 만들어 놓고 계속 재활용할 수 있어요.

두 번째는 코드를 깔끔하게 정리하기 위해서입니다. 객체를 만드는 방법과 객체를 사용하는 방법을 분리해 놓으면, 코드가 훨씬 읽기 쉽고 이해하기 쉬워집니다. 마치 요리할 때 재료 준비와 조리 과정을 나누는 것처럼 말이에요.

세 번째는 새로운 종류를 쉽게 추가하기 위해서입니다. 나중에 새로운 종류의 객체가 필요하면, 팩토리만 조금 수정하면 되어요. 다른 코드들은 건드릴 필요가 없답니다.

마지막으로는 실수를 줄이기 위해서입니다. 팩토리에서 한 번만 올바르게 만들어 놓으면, 그 이후로는 항상 정확한 객체가 만들어져요. 마치 검증된 레시피로 요리하면 항상 맛있는 음식이 나오는 것처럼 말이에요.

⚙️ 팩토리 만들기 단계

이제 우리만의 팩토리를 만들어 보겠습니다. 단계별로 차근차근 따라와 주세요.

1단계: 어떤 객체들을 만들지 계획하기
먼저 우리 팩토리에서 어떤 종류의 객체들을 만들 것인지 정해야 해요. 오늘은 애완동물 객체들을 만들어 보겠습니다.

2단계: 공통점 찾기
모든 애완동물이 공통으로 가질 특징들을 찾아봅시다. 이름, 나이, 주인과 놀기, 밥 먹기 같은 것들이 있겠네요.

3단계: 팩토리 함수 틀 만들기
우리의 공장 함수를 만들어 보겠습니다.

4단계: 각 종류별 특별한 기능 추가하기
개는 짖고, 고양이는 야옹하고, 새는 노래를 부르는 것처럼 각각의 특별한 능력을 추가해 봅시다.

5단계: 테스트해보기
우리가 만든 팩토리가 잘 작동하는지 확인해 봅시다.

🧪 예제로 익혀보기

이제 실제로 팩토리를 만들어 보는 흥미로운 시간입니다. 처음에는 간단한 것부터 시작해서 점점 더 멋진 팩토리를 만들어 보겠어요.

🔹 예제 1: 우리 반 친구들 팩토리 만들기

첫 번째 예제에서는 우리 반 친구들을 표현하는 객체를 만들어주는 팩토리를 만들어 보겠습니다. 각 친구마다 특별한 취미와 능력이 있다는 설정이에요.

// Ex1) 우리 반 친구들을 만들어주는 특별한 공장을 만들어보자
function createClassmate(type, options = {}) {
  // 모든 친구들이 공통으로 가지는 기본 특징들
  const classmate = {
    type: type,                    // 친구의 타입 (책벌레, 운동선수, 예술가)
    name: options.name || "새로운 친구",      // 친구의 이름 (기본값: "새로운 친구")
    age: options.age || 10,                   // 친구의 나이 (기본값: 10)
    grade: options.grade || "5학년",          // 친구의 학년 (기본값: "5학년")

    // 모든 친구들이 할 수 있는 공통 활동들
    sayHello: function() {
      console.log(`안녕! 나는 ${this.name}이야. ${this.grade} ${this.type}야!`);
    },

    goToSchool: function() {
      console.log(`${this.name}이 학교에 갑니다.`);
    },

    getInfo: function() {
      return `이름: ${this.name}, 나이: ${this.age}세, 학년: ${this.grade}`;  // 친구 정보 반환
    }
  };

  // 친구 타입에 따라 특별한 취미와 능력 추가하기
  if (type === "책벌레") {
    classmate.favoriteBook = options.favoriteBook || "해리포터";     // 좋아하는 책 (기본값: "해리포터")
    classmate.readingSpeed = options.readingSpeed || "빠름";         // 읽기 속도 (기본값: "빠름")

    classmate.readBook = function() {
      console.log(`${this.name}이 ${this.favoriteBook}를 열심히 읽고 있어요!`);
    };

    classmate.recommendBook = function() {
      console.log(`${this.favoriteBook} 정말 재미있어! 너도 읽어봐!`);
    };
  } 
  else if (type === "운동선수") {
    classmate.favoriteSport = options.favoriteSport || "축구";       // 좋아하는 스포츠 (기본값: "축구")
    classmate.level = options.level || "초급";                      // 실력 수준 (기본값: "초급")

    classmate.exercise = function() {
      console.log(`${this.name}이 ${this.favoriteSport} 연습을 시작합니다!`);
    };

    classmate.compete = function() {
      console.log(`${this.favoriteSport} 시합에서 최선을 다할게요!`);
    };
  }
  else if (type === "예술가") {
    classmate.artType = options.artType || "그림";                  // 예술 분야 (기본값: "그림")
    classmate.favoriteColor = options.favoriteColor || "파란색";    // 좋아하는 색깔 (기본값: "파란색")

    classmate.createArt = function() {
      console.log(`${this.name}이 아름다운 ${this.artType}을 그리고 있어요!`);
    };

    classmate.showArt = function() {
      console.log(`${this.favoriteColor}을 사용해서 만든 작품을 보여줄게요!`);
    };
  }

  return classmate;  // 완성된 친구 객체를 돌려줘요
}

// 우리 팩토리로 다양한 친구들 만들어보기
const bookworm = createClassmate("책벌레", {
  name: "지혜",                      // 친구 이름
  age: 11,                          // 친구 나이
  favoriteBook: "과학동화",          // 좋아하는 책
  readingSpeed: "매우 빠름"          // 읽기 속도
});

bookworm.sayHello();        // "안녕! 나는 지혜야. 5학년 책벌레야!"
bookworm.readBook();        // "지혜이 과학동화를 열심히 읽고 있어요!"
bookworm.recommendBook();   // "과학동화 정말 재미있어! 너도 읽어봐!"

const athlete = createClassmate("운동선수", {
  name: "민수",                      // 친구 이름
  favoriteSport: "농구",             // 좋아하는 스포츠
  level: "중급"                      // 실력 수준
});

athlete.sayHello();    // "안녕! 나는 민수야. 5학년 운동선수야!"
athlete.exercise();    // "민수이 농구 연습을 시작합니다!"

🔹 예제 2: 학용품 팩토리 만들기

두 번째 예제에서는 학교에서 사용하는 다양한 학용품을 만들어주는 팩토리를 만들어 보겠습니다.

// Ex2) 유용한 학용품을 만들어주는 공장을 만들어보자
function createSchoolSupply(type, options = {}) {
  // 모든 학용품의 공통 속성들
  const supply = {
    type: type,                            // 학용품의 종류
    brand: options.brand || "좋은 브랜드",   // 브랜드 (기본값: "좋은 브랜드")
    color: options.color || "기본색",       // 색깔 (기본값: "기본색")
    price: options.price || 1000,          // 가격 (기본값: 1000)

    // 공통 기능들
    use: function() {
      console.log(`${this.color} ${this.type}을 사용합니다.`);
    },

    getInfo: function() {
      return `${this.brand} ${this.type} (${this.color}, ${this.price}원)`;  // 학용품 정보 반환
    }
  };

  // 타입별 특별한 기능 추가하기
  if (type === "연필") {
    supply.hardness = options.hardness || "HB";      // 연필 진하기 (기본값: "HB")

    supply.write = function() {
      console.log(`${this.hardness} 연필로 글씨를 씁니다.`);
    };

    supply.sharpen = function() {
      console.log("연필을 깎습니다!");
    };
  } 
  else if (type === "지우개") {
    supply.shape = options.shape || "네모";          // 지우개 모양 (기본값: "네모")

    supply.erase = function() {
      console.log(`${this.shape} 지우개로 깨끗하게 지웁니다.`);
    };
  }
  else if (type === "공책") {
    supply.pages = options.pages || 30;              // 공책 페이지 수 (기본값: 30)
    supply.lineType = options.lineType || "줄";      // 줄 종류 (기본값: "줄")

    supply.writeIn = function() {
      console.log(`${this.lineType} 공책에 예쁘게 씁니다.`);
    };

    supply.countPages = function() {
      console.log(`이 공책은 총 ${this.pages}장입니다.`);
    };
  }

  return supply;  // 완성된 학용품 반환
}

// 사용 예시
const myPencil = createSchoolSupply("연필", {
  brand: "모나미",              // 연필 브랜드
  color: "노란색",              // 연필 색깔
  hardness: "2B"               // 연필 진하기
});

myPencil.use();      // "노란색 연필을 사용합니다."
myPencil.write();    // "2B 연필로 글씨를 씁니다."
myPencil.sharpen();  // "연필을 깎습니다!"
console.log(myPencil.getInfo()); // "모나미 연필 (노란색, 1000원)"

🔹 예제 3: 교통수단 팩토리 만들기

세 번째 예제는 다양한 교통수단을 만들어주는 팩토리입니다. 각 교통수단마다 다른 특징을 갖고 있어요.

// Ex3) 다양한 교통수단을 만들어주는 공장을 만들어보자
function createVehicle(type, options = {}) {
  // 모든 교통수단의 기본 속성과 기능들
  const vehicle = {
    type: type,                        // 교통수단의 종류
    name: options.name || `${type} 1호`,      // 교통수단 이름 (기본값: "[종류] 1호")
    speed: options.speed || 50,               // 최대 속도 (기본값: 50)
    currentSpeed: 0,                          // 현재 속도

    // 모든 교통수단이 할 수 있는 기본 명령들
    start: function() {
      console.log(`${this.name}이 출발합니다!`);
    },

    stop: function() {
      this.currentSpeed = 0;      // 현재 속도를 0으로 설정
      console.log(`${this.name}이 멈췄습니다!`);
    },

    accelerate: function() {
      this.currentSpeed = Math.min(this.speed, this.currentSpeed + 10);  // 속도 증가
      console.log(`가속합니다! 현재 속도: ${this.currentSpeed}km/h`);
    },

    getStatus: function() {
      console.log(`${this.name} - 현재 속도: ${this.currentSpeed}km/h, 최대 속도: ${this.speed}km/h`);
    }
  };

  // 교통수단 타입에 따른 특별한 기능들
  if (type === "자동차") {
    vehicle.fuel = options.fuel || 100;         // 연료량 (기본값: 100)
    vehicle.wheels = 4;                         // 바퀴 개수

    vehicle.honk = function() {
      console.log("빵빵! 🚗");      // 자동차 경적 소리
    };

    vehicle.refuel = function() {
      this.fuel = 100;             // 연료를 가득 채워요
      console.log("연료를 가득 충전했습니다!");
    };
  } 
  else if (type === "자전거") {
    vehicle.gear = options.gear || 1;           // 기어 (기본값: 1)
    vehicle.wheels = 2;                         // 바퀴 개수

    vehicle.ring = function() {
      console.log("딸랑딸랑! 🔔");   // 자전거 벨 소리
    };

    vehicle.changeGear = function(newGear) {
      this.gear = newGear;         // 기어를 바꿔요
      console.log(`기어를 ${newGear}단으로 변경했습니다!`);
    };
  }
  else if (type === "비행기") {
    vehicle.altitude = 0;                       // 현재 고도
    vehicle.maxAltitude = options.maxAltitude || 10000;  // 최대 고도 (기본값: 10000)

    vehicle.takeOff = function() {
      this.altitude = 1000;        // 고도를 1000m로 설정
      console.log(`✈️ 이륙했습니다! 현재 고도: ${this.altitude}m`);
    };

    vehicle.land = function() {
      this.altitude = 0;           // 고도를 0으로 설정
      console.log(`🛬 안전하게 착륙했습니다!`);
    };
  }

  return vehicle;  // 완성된 교통수단을 돌려줘요
}

// 교통수단 팩토리로 다양한 교통수단 만들어보기
const myCar = createVehicle("자동차", {
  name: "빨간 승용차",             // 자동차 이름
  speed: 120,                     // 최대 속도
  fuel: 80                        // 연료량
});

myCar.start();           // "빨간 승용차이 출발합니다!"
myCar.accelerate();      // "가속합니다! 현재 속도: 10km/h"
myCar.honk();            // "빵빵! 🚗"
myCar.getStatus();       // "빨간 승용차 - 현재 속도: 10km/h, 최대 속도: 120km/h"

const myBike = createVehicle("자전거", {
  name: "파란 자전거",            // 자전거 이름
  speed: 30,                     // 최대 속도
  gear: 3                        // 기어
});

myBike.start();          // "파란 자전거이 출발합니다!"
myBike.ring();           // "딸랑딸랑! 🔔"
myBike.changeGear(5);    // "기어를 5단으로 변경했습니다!"

🔄 팩토리 만들기 과정 정리

지금까지 배운 팩토리 만들기 과정을 차근차근 정리해 보겠습니다.

첫 번째 단계는 계획 세우기입니다. 어떤 종류의 객체들을 만들 것인지, 각각이 어떤 특징을 가져야 하는지 미리 생각해 보는 거예요. 마치 집을 짓기 전에 설계도를 그리는 것처럼 말이죠.

두 번째는 공통점 찾기 단계입니다. 만들려는 모든 객체가 공통으로 가져야 할 속성과 기능들을 찾아내는 과정이에요. 이것들이 우리 팩토리의 기본 틀이 됩니다.

세 번째는 팩토리 함수 만들기입니다. function create객체이름(type, options = {}) 형태로 기본 틀을 만드는 거예요. 여기서 type은 어떤 종류의 객체를 만들지를 정하고, options는 사용자가 원하는 설정들을 받는 부분입니다.

네 번째는 공통 기능 구현하기입니다. 모든 객체가 가져야 할 기본 속성과 기능들을 만들어 주는 단계예요. 이 부분은 어떤 타입이든 상관없이 모두 똑같이 적용됩니다.

다섯 번째는 타입별 특별 기능 추가하기입니다. if문이나 switch문을 사용해서 각 타입에 맞는 특별한 속성과 기능들을 추가해 주는 과정이에요.

마지막으로 테스트하고 개선하기 단계입니다. 우리가 만든 팩토리가 제대로 작동하는지 확인하고, 문제가 있으면 고치고, 더 나은 기능이 있으면 추가하는 과정입니다.

🧚‍♀️ 이야기로 다시 배우기: 현명한 학교의 제작 교실

지금까지 배운 내용을 하나의 따뜻한 이야기로 다시 정리해볼까요?

어느 현명한 학교에 제작 교실이라는 특별한 곳이 있었습니다. 이 교실에는 만능 제작 시스템이 있었는데, 학생들이 필요한 것을 말하면 자연스럽게 만들어주었어요.

예를 들어 "학용품이 필요해요"라고 말하면, 시스템이 먼저 모든 학용품의 기본 특징을 만들어줘요. 깨끗하고, 사용하기 편하며, 내구성이 좋다는 기본적인 특성들 말이에요.

그다음 "연필이 필요해요"라고 구체적으로 말하면, 시스템이 연필만의 특별한 기능들을 추가해줘요. 글쓰기, 연필 깎기 같은 연필만 할 수 있는 일들을 말이에요.

학생들은 이 시스템이 너무 편리해서 "현명한 학교 최고!"라고 외쳤어요. 복잡한 제작 과정은 시스템이 알아서 처리하고, 자신들은 필요한 것만 간단히 말하면 되니까 정말 편했거든요.

이것이 바로 팩토리 패턴의 장점이에요! 복잡한 만들기 과정은 공장(팩토리)이 처리하고, 우리는 간단한 주문만 하면 원하는 물건을 받을 수 있는 거죠.

🧠 자주 하는 실수와 주의할 점

팩토리를 만들 때 초보자들이 자주 하는 실수들을 미리 알아두면 더 좋은 팩토리를 만들 수 있어요.

❌ 실수 1: 타입 이름을 정확히 쓰지 않기

// 이렇게 하면 안돼요 - 타입 이름이 틀렸을 때 처리가 없어요
function createAnimal(type) {
    if (type === "강아지") {
        // 강아지 만들기
        return { name: "강아지", sound: "멍멍" };    // 강아지 객체 반환
    } else if (type === "고양이") {
        // 고양이 만들기
        return { name: "고양이", sound: "야옹" };    // 고양이 객체 반환
    }
    // "강아지" 대신 "개"라고 쓰면 아무것도 만들어지지 않아요!
}

// 개선된 방법
const ANIMAL_TYPES = {
  DOG: "강아지",
  CAT: "고양이"
};

function createAnimal(type) {
  if (type === ANIMAL_TYPES.DOG) {
    return { name: "강아지", sound: "멍멍" };
  } else if (type === ANIMAL_TYPES.CAT) {
    return { name: "고양이", sound: "야옹" };
  } else {
    console.warn(`알 수 없는 동물 타입: ${type}`);
    return { name: "알 수 없는 동물", sound: "..." };
  }
}

❌ 실수 2: 옵션을 제대로 처리하지 않기

// 이렇게 하면 안돼요 - 옵션이 없을 때 에러가 날 수 있어요
function createToy(type, options) {
    const toy = {
        name: options.name,      // options가 없으면 에러!
        color: options.color     // 이것도 에러!
    };
    return toy;                  // 객체 반환
}

// 개선된 방법
function createToy(type, options = {}) {
    const toy = {
        name: options.name || `기본 ${type}`,      // 기본값 설정
        color: options.color || "무색"             // 기본값 설정
    };
    return toy;
}

✏️ 연습문제로 개념 다지기

조용한 마음으로 배운 내용을 연습문제를 통해 차근차근 익혀보겠습니다.

Q1. 음료수 팩토리 만들기

// Ex1) 시원한 음료수를 만들어주는 공장을 만들어보자
function createDrink(type, options = {}) {
  // 모든 음료수의 기본 특징
  const drink = {
    type: type,
    name: options.name || `기본 ${type}`,
    size: options.size || "중간",
    temperature: options.temperature || "차가운",

    serve: function() {
      console.log(`${this.temperature} ${this.size} ${this.name}를 서빙합니다.`);
    },

    getInfo: function() {
      return `${this.name} (${this.size}, ${this.temperature})`;
    }
  };

  // 음료수 타입에 따른 특별한 특징들
  if (type === "콜라") {
    drink.carbonated = true;
    drink.fizz = function() {
      console.log("쉬이익~ 탄산이 톡톡! ✨");
    };
  } 
  else if (type === "주스") {
    drink.fruit = options.fruit || "오렌지";
    drink.healthy = function() {
      console.log(`${this.fruit} 비타민이 풍부해서 건강에 좋아요!`);
    };
  }
  else if (type === "물") {
    drink.pure = true;
    drink.refresh = function() {
      console.log("깔끔하게 갈증이 해소되었어요!");
    };
  }

  return drink;
}

// 사용 예시
const cola = createDrink("콜라", {
  name: "시원한 콜라",
  size: "큰"
});

cola.serve();  // "차가운 큰 시원한 콜라를 서빙합니다."
cola.fizz();   // "쉬이익~ 탄산이 톡톡! ✨"

Q2. 게임 캐릭터 팩토리 만들기

// Ex2) 멋진 게임 캐릭터를 만들어주는 팩토리를 만들어보자
function createGameCharacter(type, options = {}) {
  // 모든 캐릭터의 공통 속성들
  const character = {
    type: type,
    name: options.name || `용감한 ${type}`,
    level: options.level || 1,
    health: options.health || 100,

    introduce: function() {
      console.log(`안녕! 나는 ${this.level}레벨 ${this.name}이야!`);
    },

    checkStatus: function() {
      console.log(`체력: ${this.health}`);
    },

    levelUp: function() {
      this.level++;
      console.log(`축하합니다! ${this.level}레벨이 되었어요!`);
    }
  };

  // 캐릭터 타입별 특별한 능력 추가하기
  if (type === "전사") {
    character.weapon = options.weapon || "검";
    character.attack = function() {
      console.log(`⚔️ ${this.weapon}으로 강력하게 공격합니다!`);
    };
  } 
  else if (type === "마법사") {
    character.mana = options.mana || 50;
    character.castSpell = function() {
      console.log("🔮 신비한 마법을 시전합니다!");
    };
  }
  else if (type === "궁수") {
    character.arrows = options.arrows || 20;
    character.shoot = function() {
      console.log("🏹 정확한 화살을 쏩니다!");
    };
  }

  return character;
}

// 사용 예시
const warrior = createGameCharacter("전사", {
  name: "용감한 김전사",
  level: 5,
  weapon: "마법 검"
});

warrior.introduce();  // "안녕! 나는 5레벨 용감한 김전사야!"
warrior.attack();     // "⚔️ 마법 검으로 강력하게 공격합니다!"

📚 이전에 배운 것들 되돌아보기

18단원을 배우고 있는 여러분! 지금까지 정말 많은 것들을 배웠네요. 이전에 배운 중요한 내용들을 잠시 되돌아보면서 기억을 되살려보겠어요.

🎯 되돌아보기 1: 클래스와 상속 (15-16단원)

// Q: 다음 클래스 상속 코드의 실행 결과를 예상해보세요!

class 교통수단 {
  constructor(이름) {
    this.이름 = 이름;
    this.속도 = 0;
  }

  출발하기() {
    console.log(`${this.이름}이(가) 출발합니다!`);
  }
}

class 자동차 extends 교통수단 {
  constructor(이름, 연료량) {
    super(이름);                    // 부모 클래스 생성자 호출
    this.연료량 = 연료량;
  }

  출발하기() {                      // 메서드 오버라이딩
    if (this.연료량 > 0) {
      console.log(`${this.이름}이(가) 부릉부릉 출발합니다!`);
    } else {
      console.log("연료가 부족해요!");
    }
  }
}

const 내차 = new 자동차("소나타", 50);
내차.출발하기();                    // ?

해답과 설명:
내차.출발하기(); → "소나타이(가) 부릉부릉 출발합니다!"

설명: extends 키워드로 상속받으면 부모의 모든 기능을 물려받아요. 자식 클래스에서 같은 이름의 메서드를 만들면 부모 메서드를 덮어쓸 수 있어요(오버라이딩).

🎯 되돌아보기 2: 비동기 처리 (13단원)

// Q: 다음 코드의 실행 순서를 예상해보세요!

console.log("1. 학교 도착");

setTimeout(() => {
  console.log("2. 3초 후 수업 시작");
}, 3000);

Promise.resolve("3. 책 준비 완료")
  .then(결과 => {
    console.log(결과);
    return "4. 필기도구 준비 완료";
  })
  .then(결과 => {
    console.log(결과);
  });

console.log("5. 자리에 앉기");

해답과 설명:
실행 순서:

  1. "1. 학교 도착" (동기 코드)
  2. "5. 자리에 앉기" (동기 코드)
  3. "3. 책 준비 완료" (Promise)
  4. "4. 필기도구 준비 완료" (Promise)
  5. "2. 3초 후 수업 시작" (setTimeout, 3초 후)

설명: 동기 코드가 먼저 실행되고, Promise가 setTimeout보다 우선순위가 높아요.

🎯 되돌아보기 3: 모듈 시스템 (17단원)

// Q: 다음 모듈 코드를 분석해보세요!

// 도구함.js 파일
export function 더하기(a, b) {
  return a + b;
}

export function 빼기(a, b) {
  return a - b;
}

export default function 곱하기(a, b) {
  return a * b;
}

// main.js 파일
import 곱하기, { 더하기, 빼기 } from './도구함.js';

console.log(더하기(5, 3));        // ?
console.log(빼기(10, 4));         // ?
console.log(곱하기(2, 6));        // ?

해답과 설명:

  • 더하기(5, 3) → 8
  • 빼기(10, 4) → 6
  • 곱하기(2, 6) → 12

설명: export default는 기본 내보내기로 중괄호 없이 가져올 수 있고, 일반 export는 중괄호 안에 넣어서 가져와야 해요.

🤔 조금 더 깊이 생각해보기

Q1. 다음 코드의 문제점을 찾고 더 나은 팩토리로 개선해보세요.

// 문제가 있는 코드
function createItem(type) {
  if (type === "sword") {
    return { type: "sword", damage: 10 };
  } else if (type === "shield") {
    return { type: "shield", defense: 5 };
  }
  // 다른 타입이 들어오면 어떻게 될까요?
}

개선된 코드:

// 팩토리 패턴을 사용한 개선 코드
function createItem(type, options = {}) {
  // 모든 아이템의 공통 속성
  const item = {
    type: type,
    name: options.name || `기본 ${type}`,
    durability: options.durability || 100,
    rarity: options.rarity || "일반",

    // 공통 기능
    getInfo: function() {
      return `${this.name} (${this.rarity}, 내구도: ${this.durability})`;
    },

    use: function() {
      this.durability = Math.max(0, this.durability - 1);
      console.log(`${this.name}을 사용했습니다. 내구도: ${this.durability}`);
    }
  };

  // 아이템 타입별 특별한 기능 추가
  if (type === "검") {
    item.damage = options.damage || 10;
    item.attack = function() {
      console.log(`${this.name}으로 ${this.damage} 데미지를 입힙니다!`);
    };
  } 
  else if (type === "방패") {
    item.defense = options.defense || 5;
    item.block = function() {
      console.log(`${this.name}으로 ${this.defense} 방어력만큼 막습니다!`);
    };
  }
  else if (type === "물약") {
    item.healAmount = options.healAmount || 20;
    item.drink = function() {
      console.log(`${this.name}을 마셔서 체력을 ${this.healAmount} 회복합니다!`);
    };
  }
  else {
    console.warn(`알 수 없는 아이템 타입: ${type}`);
    item.defaultAction = function() {
      console.log("기본 아이템입니다.");
    };
  }

  return item;
}

// 사용 예시
const mySword = createItem("검", {
  name: "불꽃 검",
  damage: 15,
  rarity: "희귀"
});

mySword.attack(); // "불꽃 검으로 15 데미지를 입힙니다!"
mySword.use();    // "불꽃 검을 사용했습니다. 내구도: 99"

지금까지 객체 생성 팩토리를 만드는 방법을 자세히 배웠습니다. 처음에는 조금 어려울 수 있지만, 연습을 통해 점점 익숙해질 거예요. 팩토리 패턴은 앞으로 더 복잡한 프로그램을 만들 때 정말 유용한 도구가 될 것입니다.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
팩토리 만들기의 기본 개념
팩토리를 만드는 단계별 과정
타입별 기능 추가하는 방법
자주 하는 실수들과 주의점
실전 예제를 통한 활용법

📂 마무리 정보

오늘 배운 18.2.2 내용이 여러분의 자바스크립트 지식 상자에 잘 정리되었나요? 다음 시간에는 또 다른 흥미로운 내용으로 만나요!

기억할 점: 팩토리 패턴은 복잡한 객체 생성 과정을 간단하게 만들어주는 정말 유용한 도구예요!


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작