Post

๐ŸŽจ 04. ํŒฉํ† ๋ฆฌ ํŒจํ„ด

๐ŸŽจ 04. ํŒฉํ† ๋ฆฌ ํŒจํ„ด

๐Ÿญย โ€™newโ€™ ์—ฐ์‚ฐ์ž๊ฐ€ ๋ˆˆ์— ๋ˆ๋‹ค๋ฉด โ€˜๊ตฌ์ƒโ€™์ด๋ผ๋Š” ์šฉ์–ด๋ฅผ ๋– ์˜ฌ๋ ค ์ฃผ์„ธ์š”.

new๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค. ๊ตฌ์ƒ ํด๋ž˜์Šค๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ฝ”๋”ฉํ•˜๋ฉด ๋‚˜์ค‘์— ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์ง€๊ณ , ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Duck ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
interface Duck {
  quack(): void;
  swim(): void;
}

.
.
.

let duck: Duck;

if (picnic) {
  duck = new MallardDuck();
} else if (hunting) {
  duck = new DecoyDuck();
} else if (inBathTub) {
  duck = new RubberDuck();
}

duck.quack();
duck.swim();

๐Ÿ” ์ด ์ฝ”๋“œ์˜ ๋ฌธ์ œ์  (๊ตฌ์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜๋Š” ๋ฌธ์ œ)

MallardDuck, DecoyDuck, RubberDuck์— ์ง์ ‘ new๋ฅผ ํ•˜๊ณ  ์žˆ์Œ โ†’ ๊ตฌ์ƒ ํด๋ž˜์Šค์— ๊ฐ•ํ•˜๊ฒŒ ์˜์กดํ•จ

  • ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์œผ๋ฉฐ(= Duck ํƒ€์ž…์˜ ์—ฌ๋Ÿฌ ๊ตฌํ˜„์ฒด๊ฐ€ ์กด์žฌ), ๊ทธ ์ธ์Šคํ„ด์Šค์˜ ํ˜•์‹์€ ์‹คํ–‰ ์‹œ์— ์ฃผ์–ด์ง„ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.

์ด๊ฑด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๊ณ , ์ƒˆ๋กœ์šด ์˜ค๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค if-else ๊ตฌ๋ฌธ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ๋ฅผ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋งŒ๋“ค๋ฉด ๊ด€๋ฆฌ์™€ ๊ฐฑ์‹ ์ด ์–ด๋ ค์›Œ์ง€๊ณ  ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ๋„ ์ปค์ง„๋‹ค.

๐Ÿ” โ€˜newโ€™ ์— ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฑธ๊นŒ์š”?

์‚ฌ์‹ค new์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๊ณ , ์ง„์งœ ๋ง์ฝ์„ ์ผ์œผํ‚ค๋Š” ๋…€์„์€ ๋ฐ”๋กœ โ€˜๋ณ€ํ™”โ€™์ด๋‹ค! ๋ณ€ํ™”ํ•˜๋Š” ๋ฌด์–ธ๊ฐ€ ๋•Œ๋ฌธ์— new๋ฅผ ์กฐ์‹ฌํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

โœ…ย ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ฝ”๋“œ๋Š” ์–ด๋–ค ํด๋ž˜์Šค๋“  ํŠน์ • ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋‹คํ˜•์„ฑ(Polymorphism)
    • ๊ฐ™์€ ํƒ€์ž…์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Animal {
  speak(): void;
}

class Dog implements Animal {
  speak() {
    console.log("๋ฉ");
  }
}

class Cat implements Animal {
  speak() {
    console.log("๋จ€");
  }
}

// ์ด ํ•จ์ˆ˜๋Š” Animal๋งŒ ์•Œ๊ณ  Dog, Cat์€ ๋ชจ๋ฆ„
function makeSound(animal: Animal) {
  animal.speak(); // ์–ด๋–ค ๋™๋ฌผ์ด ์™€๋„ ์‹คํ–‰๋จ
}

makeSound(new Dog()); // ๋ฉ
makeSound(new Cat()); // ๋จ€

โŒย ๊ตฌ์ƒ ํด๋ž˜์Šค๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ๊ตฌ์ƒ ํด๋ž˜์Šค๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ฝ”๋“œ๋ฅผ ๊ณ ์ณ์•ผ ํ•˜๋ฏ€๋กœ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

  • ์ฆ‰, ๋ณ€๊ฒฝ์— ๋‹ซํ˜€ ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ๋˜๋Š” ๊ฒƒ
1
2
3
4
5
6
7
8
9
function playWithAnimal(type: string) {
  if (type === "dog") {
    const dog = new Dog();
    dog.speak();
  } else if (type === "cat") {
    const cat = new Cat();
    cat.speak();
  }
}
  • ์ƒˆ๋กœ์šด ๊ตฌ์ƒ ํ˜•์‹์„ ์จ์„œ ํ™•์žฅํ•ด์•ผ ํ•  ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์„œ๋“  ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
    • OCP (๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™)
    • ์ฝ”๋“œ ๋‚ด๋ถ€๋ฅผ ๊ณ„์† ์ˆ˜์ •ํ•˜์ง€ ๋ง๊ณ  ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋ฐ–์—์„œ โ€œ๋ผ์›Œ๋„ฃ์„ ์ˆ˜ ์žˆ๋„๋กโ€ ๋งŒ๋“ค์–ด๋ผ!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function playWithAnimal(animal: Animal) {
  animal.speak();
}

// ์ƒˆ๋กœ์šด ๋™๋ฌผ์ด ์ƒ๊น€
class Parrot implements Animal {
  speak() {
    console.log("์•ˆ๋…•");
  }
}

// ๊ธฐ์กด ํ•จ์ˆ˜๋Š” ์ ˆ๋Œ€ ์•ˆ ๊ณ ์น˜๊ณ  ๊ทธ๋ƒฅ ์ƒˆ๋กœ ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋จ
playWithAnimal(new Parrot()); // ์•ˆ๋…•

โœจ ์ด๋ ‡๊ฒŒ ๋˜๋ฉด playWithAnimal() ํ•จ์ˆ˜๋Š” ์ ˆ๋Œ€ ๊ณ ์น˜์ง€ ์•Š์•„๋„ ๋˜๊ณ , ์ƒˆ ๋™๋ฌผ์ด ์ถ”๊ฐ€๋ ์ˆ˜๋ก ํ™•์žฅ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๊ธฐ์กด ์ฝ”๋“œ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๊ฒƒ

๐Ÿ’ก ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ถ€๋ถ„์„ ์ „๋ถ€ ์ฐพ์•„๋‚ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์œผ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ(์บก์Аํ™”)ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿญย ์ตœ์ฒจ๋‹จ ํ”ผ์ž ์ฝ”๋“œ ๋งŒ๋“ค๊ธฐ

๊ฐ์ฒด ๋งˆ์„์˜ ์ตœ์ฒจ๋‹จ ํ”ผ์ž ๊ฐ€๊ฒŒ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘์—ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
function orderPizza(): Pizza {
  const pizza = new Pizza();

  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();

  return pizza;
}

๊ทผ๋ฐ ํ”ผ์ž ์ข…๋ฅ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ž„โ€ฆ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function orderPizza(type: string): Pizza {
  let pizza: Pizza;

  if (type === "cheese") {
    pizza = new CheesePizza();
  } else if (type === "greek") {
    pizza = new GreekPizza();
  } else if (type === "pepperoni") {
    pizza = new PepperoniPizza();
  } else {
    throw new Error(`์•Œ ์ˆ˜ ์—†๋Š” ํ”ผ์ž ํƒ€์ž…: ${type}`);
  }

  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();

  return pizza;
}

๐Ÿญย ํ”ผ์ž ์ฝ”๋“œ ์ถ”๊ฐ€ํ•˜๊ธฐ

๋งž์€ํŽธ์— ์žˆ๋Š” ํ”ผ์ž ๊ฐ€๊ฒŒ์—์„œ ์‹ ๋ฉ”๋‰ด๋ฅผ 2๊ฐœ๋‚˜ ์ถœ์‹œํ–ˆ๋‹ค. ์กฐ๊ฐœ ํ”ผ์ž์™€ ์•ผ์ฑ„ ํ”ผ์ž! ์ตœ์ฒจ๋‹จ ํ”ผ์ž ๊ฐ€๊ฒŒ๋„ ๋”ฐ๋ผ์„œ ๋˜‘๊ฐ™์€ ์‹ ๋ฉ”๋‰ด๋ฅผ ์ถœ์‹œํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ์ด์ฐธ์— ๋ณ„๋กœ ์•ˆ ํŒ”๋ฆฌ๋Š” ๊ทธ๋ฆฌ์Šค ์Šคํƒ€์ผ ํ”ผ์ž๋Š” ๋ฉ”๋‰ด์—์„œ ์ œ์™ธํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function orderPizza(type: string): Pizza {
  let pizza: Pizza;

  if (type === "cheese") {
    pizza = new CheesePizza();
  } else if (type === "pepperoni") {
    pizza = new PepperoniPizza();
  } else if (type === "clam") { // ์ถ”๊ฐ€๋จ
    pizza = new ClamPizza();
  } else if (type === "veggie") { // ์ถ”๊ฐ€๋จ
    pizza = new VeggiePizza();
  } else {
    throw new Error(`์•Œ ์ˆ˜ ์—†๋Š” ํ”ผ์ž ํƒ€์ž…: ${type}`);
  }
  // greekPizza ์‚ญ์ œ

  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();

  return pizza;
}
  • if~else
    • ์ด ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ์— ๋‹ซํ˜€ ์žˆ์ง€ ์•Š๋‹ค. ํ”ผ์ž ๊ฐ€๊ฒŒ์—์„œ ๋ฉ”๋‰ด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด if-else ๊ตฌ๋ฌธ์„ ๊ณ„์† ๊ณ ์ณ์•ผ ํ•œ๋‹ค.
  • pizza.prepare() ~ pizza.box()
    • ์ด ๋ถ€๋ถ„์€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค. ๊ตฝ๊ณ , ์ž๋ฅด๊ณ , ํฌ์žฅํ•˜๋Š” ์ผ์€ ํ”ผ์ž๋ฅผ ํŒ๋งคํ•  ๋•Œ ๋‹น์—ฐํžˆ ํ•ด์•ผ ํ•˜๋Š” ์ผ์ด๋ฏ€๋กœ ์ด ์ฝ”๋“œ๋Š” ๊ณ ์น  ์ผ์ด ๊ฑฐ์˜ ์—†๋‹ค. ํ˜ธ์ถœํ•˜๋Š” ํ”ผ์ž ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋งŒ ๋‹ฌ๋ผ์งˆ ๋ฟ์ด๋‹ค.
  • orderPizza() ๋ฉ”์†Œ๋“œ์—์„œ ๊ฐ€์žฅ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ตฌ์ƒ ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. ์ด ๋ถ€๋ถ„ ๋•Œ๋ฌธ์— ์ƒํ™ฉ์ด ๋ณ€ํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿญย ๊ฐ์ฒด ์ƒ์„ฑ ๋ถ€๋ถ„ ์บก์Аํ™”ํ•˜๊ธฐ

๊ฐ์ฒด ์ƒ์„ฑ ๋ถ€๋ถ„์„ orderPizza() ๋ฉ”์†Œ๋“œ์—์„œ ๋ฝ‘์•„๋‚ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ข‹์„๊นŒ? ์šฐ์„  ๊ฐ์ฒด ์ƒ์„ฑ ์ฝ”๋“œ๋งŒ ๋”ฐ๋กœ ๋นผ์„œ ํ”ผ์ž ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ์ผ๋งŒ ์ „๋‹ดํ•˜๋Š” ๊ฐ์ฒด โ‡’ SimplePizzaFactory์— ๋„ฃ์–ด๋ณด์ž.

์ƒˆ๋กœ ๋งŒ๋“ค ๊ฐ์ฒด๋ฅผ ํŒฉํ† ๋ฆฌ๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ์ฒด ์ƒ์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ํŒฉํ† ๋ฆฌ(Factory)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์ผ๋‹จ SimplePizzaFactory๋ฅผ ๋งŒ๋“ค๊ณ  ๋‚˜๋ฉด orderPizza() ๋ฉ”์†Œ๋“œ๋Š” ์ƒˆ๋กœ ๋งŒ๋“  ๊ฐ์ฒด์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋œ๋‹ค. ์ฆ‰, ์ƒˆ๋กœ ๋งŒ๋“  ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋” ์ด์ƒ orderPizza() ๋ฉ”์†Œ๋“œ์—์„œ ์–ด๋–ค ํ”ผ์ž๋ฅผ ๋งŒ๋“ค์ง€ ๊ณ ๋ฏผํ•˜์ง€ ์•Š๊ณ , Pizza ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”ผ์ž๋ฅผ ๋ฐ›์•„์„œ ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ •์˜ํ–ˆ๋˜ prepare(), bake(), cut(), box() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿญย ๊ฐ์ฒด ์ƒ์„ฑ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

์šฐ์„  ํŒฉํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž. ํ”ผ์ž ๊ฐ์ฒด ์ƒ์„ฑ ๋ถ€๋ถ„์„ ์ „๋‹ดํ•  ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class SimplePizzaFactory {
  createPizza(type: string): Pizza {
    if (type === "cheese") {
      return new CheesePizza();
    } else if (type === "pepperoni") {
      return new PepperoniPizza();
    } else if (type === "clam") {
      return new ClamPizza();
    } else if (type === "veggie") {
      return new VeggiePizza();
    } else {
      throw new Error(`์•Œ ์ˆ˜ ์—†๋Š” ํ”ผ์ž ํƒ€์ž…: ${type}`);
    }
  }
}
  • ์šฐ์„  createPizza() ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค.
    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ํ˜ธ์ถœํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ด๋‹ค.
  • ์ „๋‹ฌ๋ฐ›์€ ๋งค๊ฐœ๋ณ€์ˆ˜(type)๋กœ ํ”ผ์ž ์ข…๋ฅ˜๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.

๐Ÿ™‹โ€โ™€๏ธ โ€œ๊ทธ๋ƒฅ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋„˜๊ธด ๊ฒƒ๋ฟ ์•„๋‹Œ๊ฐ€์š”?โ€

์‹ค์ œ๋กœ๋„ new๋ฅผ ํŒฉํ† ๋ฆฌ๋กœ ์˜ฎ๊ธด ๊ฒƒ๋ฟ์ด๊ธด ํ•จ

ํ•˜์ง€๋งŒ โ€œ์บก์Аํ™”โ€์˜ ์ง„์งœ ๋ชฉ์ ์€ ์ฑ…์ž„์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•ด์„œ ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•œ ์„ค๊ณ„์— ์žˆ๋‹ค.

๐Ÿ” ๋‹จ์ˆœ ๋น„๊ต

1
2
3
4
5
6
function orderPizza(type: string): Pizza {
  if (type === "cheese") {
    return new CheesePizza();
  }
  // ...
}
  • orderPizza()๊ฐ€ ํ”ผ์ž ์ข…๋ฅ˜๋ฅผ ๋‹ค ์•Œ์•„์•ผ ํ•จ
  • ์ƒˆ๋กœ์šด ํ”ผ์ž ์ถ”๊ฐ€๋˜๋ฉด ์ด ์ฝ”๋“œ๋„ ๊ณ„์† ๋ฐ”๋€œ โ†’ OCP ์œ„๋ฐ˜
  • ๋‹จ์ผ ์ฑ…์ž„ ์›์น™(SRP)๋„ ๊นจ์ง โ†’ โ€œ์ฃผ๋ฌธโ€๊ณผ โ€œ์ƒ์„ฑโ€ ๋‘˜ ๋‹ค ์ฑ…์ž„์ง

๐Ÿ‘ ํŒฉํ† ๋ฆฌ์— ์œ„์ž„

1
const pizza = factory.createPizza(type);
  • ํ”ผ์ž ์ข…๋ฅ˜๋ฅผ ์•„๋Š” ๊ฑด SimplePizzaFactory์˜ ์ฑ…์ž„
  • orderPizza()๋Š” ์˜ค์ง ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ๋งŒ ์‹ ๊ฒฝ ์”€
  • ์ƒˆ ํ”ผ์ž ์ถ”๊ฐ€ํ•ด๋„ orderPizza()๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€ ๊ฐ€๋Šฅ

์ฆ‰, ๋‹จ์ˆœํžˆ โ€œ๋ฌธ์ œ๋ฅผ ๋„˜๊ฒผ๋‹คโ€๊ฐ€ ์•„๋‹ˆ๋ผ, ์ฑ…์ž„์„ ๋‚˜๋ˆ ์„œ ๋ณ€๊ฒฝ์— ๊ฐ•ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ ์‰ฌ์šด ๊ตฌ์กฐ๋กœ ์บก์Аํ™”ํ•œ ๊ฒƒ

๐Ÿญย ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ์ˆ˜์ •ํ•˜๊ธฐ

ํŒฉํ† ๋ฆฌ๋กœ ํ”ผ์ž ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ๊ณ ์ณ๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class SimplePizzaFactory {
  createPizza(type: string): Pizza {
    if (type === "cheese") {
      return new CheesePizza();
    } else if (type === "pepperoni") {
      return new PepperoniPizza();
    } else if (type === "clam") {
      return new ClamPizza();
    } else if (type === "veggie") {
      return new VeggiePizza();
    } else {
      throw new Error(`์•Œ ์ˆ˜ ์—†๋Š” ํ”ผ์ž ํƒ€์ž…: ${type}`);
    }
  }
}

class PizzaStore {
  constructor(private factory: SimplePizzaFactory) {}

  orderPizza(type: string): Pizza {
    const pizza = this.factory.createPizza(type); // ๐Ÿ• ์ƒ์„ฑ ์ฑ…์ž„ ์œ„์ž„!

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
  }
}

  • SimplePizzaFactory
    • ํ”ผ์ž ๋งŒ๋“œ๋Š” ๊ธฐ๊ณ„!
    • ๋ฌธ์ž์—ด(type)์„ ๋ฐ›์•„์„œ ์•Œ๋งž์€ ํ”ผ์ž ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•จ
    • ์‹ค์ œ new CheesePizza() ๊ฐ™์€ ๊ฐ์ฒด ์ƒ์„ฑ ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ํ•œ ๊ณณ์— ์ง‘์ค‘์‹œํ‚ด
  • PizzaStore
    • ์‹ค์ œ ํ”ผ์ž ๊ฐ€๊ฒŒ
    • ์†๋‹˜์ด "cheese" ๊ฐ™์€ ๋ฌธ์ž์—ด๋กœ ํ”ผ์ž๋ฅผ ์ฃผ๋ฌธํ•˜๋ฉด,
      1. SimplePizzaFactory์—๊ฒŒ ํ”ผ์ž ๋งŒ๋“ค์–ด๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•จ
      2. ๋ฐ›์€ ํ”ผ์ž ๊ฐ์ฒด๋ฅผ ์•Œ๋งž์€ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•จ (์ค€๋น„ โ†’ ๊ตฝ๊ธฐ โ†’ ์ž๋ฅด๊ธฐ โ†’ ํฌ์žฅ)

๐Ÿญย โ€™๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌโ€™์˜ ์ •์˜

๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ(Simple Factory)๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋ผ๊ธฐ ๋ณด๋‹ค๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๊ด€์šฉ๊ตฌ์— ๊ฐ€๊น๋‹ค. ๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ๋ฅผ โ€˜ํŒฉํ† ๋ฆฌ ํŒจํ„ดโ€™์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์‚ฌ๋žŒ๋“ค๋„ ์žˆ์ง€๋งŒ, ์ •ํ™•ํ•˜๊ฒŒ ํŒจํ„ด์€ ์•„๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ๋ฅผ ์™œ ์“ฐ๋Š”์ง€ ์•Œ์•„๋ณด์ž.

Image

1. PizzaStore

  • ๐Ÿ”น ์—ญํ• : ํด๋ผ์ด์–ธํŠธ
  • ๐Ÿ”น orderPizza() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ”ผ์ž๋ฅผ ์ฃผ๋ฌธ๋ฐ›์Œ
  • ๐Ÿ”น ํ”ผ์ž ์ƒ์„ฑ์— ๋Œ€ํ•ด์„  ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฆ„, ๋Œ€์‹  SimplePizzaFactory์— ์œ„์ž„ํ•จ

2. SimplePizzaFactory

  • ๐Ÿ”น ์—ญํ• : ํŒฉํ† ๋ฆฌ
  • ๐Ÿ”น createPizza() ๋ฉ”์„œ๋“œ๋กœ ์š”์ฒญ๋ฐ›์€ ํ”ผ์ž ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  • ๐Ÿ”น ์ด๊ณณ์—์„œ๋งŒ ๊ตฌ์ฒด์ ์ธ ํ”ผ์ž ํด๋ž˜์Šค(CheesePizza, ClamPizza ๋“ฑ)๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•จ
  • ๐Ÿ‘‰ ์ด ๋ถ€๋ถ„๋งŒ ๋ฐ”๊พธ๋ฉด ํ”ผ์ž ์ข…๋ฅ˜ ์ถ”๊ฐ€/์‚ญ์ œ ๊ฐ€๋Šฅ

3. Pizza

  • ๐Ÿ”น ์—ญํ• : ์ œํ’ˆ(Product)์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค
  • ๐Ÿ”น ์ถ”์ƒ ํด๋ž˜์Šค ํ˜น์€ ์ธํ„ฐํŽ˜์ด์Šค์ฒ˜๋Ÿผ ๋™์ž‘
  • ๐Ÿ”น prepare(), bake(), cut(), box() ๊ฐ™์€ ๊ณตํ†ต ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜

4. CheesePizza, ClamPizza, VeggiePizza, PepperoniPizza

  • ๐Ÿ”น ์—ญํ• : ๊ตฌ์ƒ ์ œํ’ˆ(Concrete Products)
  • ๐Ÿ”น Pizza๋ฅผ ์ƒ์†ํ•ด์„œ ์ž๊ธฐ๋งŒ์˜ prepare() ๊ตฌํ˜„์„ ์ œ๊ณต
  • ๐Ÿ”น ํŒฉํ† ๋ฆฌ์—์„œ ์ด ํด๋ž˜์Šค๋“ค์„ new ํ•ด์„œ ๋งŒ๋“ค์–ด๋ƒ„

๐Ÿ” ์ „์ฒด ํ๋ฆ„ ์š”์•ฝ

  1. PizzaStore์—์„œ "cheese"๋ผ๋Š” ์ฃผ๋ฌธ์ด ๋“ค์–ด์˜ด
  2. SimplePizzaFactory.createPizza("cheese") ํ˜ธ์ถœ
  3. ํŒฉํ† ๋ฆฌ๋Š” new CheesePizza()๋กœ ํ”ผ์ž ๊ฐ์ฒด ์ƒ์„ฑ
  4. PizzaStore๋Š” ๋ฐ›์€ ํ”ผ์ž์— ๋Œ€ํ•ด prepare(), bake() ๋“ฑ ์ฒ˜๋ฆฌ
  5. ์†๋‹˜์—๊ฒŒ ๋ฐ˜ํ™˜ ๐Ÿ•

Kohi์˜ ๋ง:

๊ทธ๋Ÿผ ๋‚ด๊ฐ€ ์•„๊นŒ๊นŒ์ง€ ํ•œ ๊ฒŒ ๋ชจ๋‘ ๋‹ค ๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ์˜€๋‹ค๊ณ โ€ฆ?

ChatGPT์˜ ๋ง:

๐Ÿ‘ ์ •ํ™•ํ•ด! ๋„ค๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ๊ตฌ์กฐ๋Š” ์ „ํ˜•์ ์ธ โ€œ๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ(Simple Factory)โ€ ํŒจํ„ด์ด์•ผ!

  1. PizzaStore์—์„œ Pizza๋ฅผ ์ง์ ‘ new๋กœ ๋งŒ๋“ค๋˜ ๊ฑธ
  2. SimplePizzaFactory๋กœ ๊ฐ์ฒด ์ƒ์„ฑ ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•˜๊ณ 
  3. PizzaStore๋Š” ์ด์ œ โ€œํ”ผ์ž๋ฅผ ์ฃผ๋ฌธ๋ฐ›๊ณ  ์ฒ˜๋ฆฌโ€ํ•˜๋Š” ์—ญํ• ๋งŒ ํ•˜๊ฒŒ ๋จ

๐Ÿ‘‰ ์ด ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋กœ ๊ฐ„๋‹จํ•œ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์˜ ๋Œ€ํ‘œ์ ์ธ ํ˜•ํƒœ

๐Ÿง  ๊ทธ๋Ÿฐ๋ฐ ์™œ โ€œํŒจํ„ดโ€์ด ์•„๋‹ˆ๋ผ โ€œ๊ด€์šฉ๊ตฌ(idiom)โ€๋ผ๊ณ  ํ• ๊นŒ?

  • GoF(๋””์ž์ธ ํŒจํ„ด์˜ ๋ฐ”์ด๋ธ”)์— ๋‚˜์˜ค๋Š” 23๊ฐ€์ง€ ๋””์ž์ธ ํŒจํ„ด์—๋Š” Simple Factory๋Š” ์—†์Œ
  • ๊ทธ ๋Œ€์‹  ์ด๊ฑด ์ž์ฃผ ์“ฐ์ด๋Š” ์œ ์šฉํ•œ ์„ค๊ณ„ ์Šต๊ด€์ด๋ผ์„œ, ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด โ€œํŒจํ„ด์ฒ˜๋Ÿผโ€ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด ๋””์ž์ธ ํŒจํ„ด์€ ์•„๋‹˜

๊ฐ์ฒด ๊ตฌ์„ฑ์„ ํ™œ์šฉํ•˜๋ฉด ํ–‰๋™์„ ์‹คํ–‰ํ•  ๋•Œ ๊ตฌํ˜„๋œ ๊ฐ์ฒด๋ฅผ ๋™์ ์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. PizzaStore์—์„œ๋„ ๊ทธ ๋ฐฉ๋ฒ•์„ ์“ธ ์ˆ˜ ์—†์„๊นŒ์š”? ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค์—์„œ ์–ด๋–ค ๋ถ€๋ถ„์„ ๋งˆ์Œ๋Œ€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์„๊นŒ์š”?

์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ๋‰ด์š• ์Šคํƒ€์ผ, ์‹œ์นด๊ณ  ์Šคํƒ€์ผ, ์บ˜๋ฆฌํฌ๋‹ˆ์•„ ์Šคํƒ€์ผ ํ”ผ์ž๋ฅผ ๋– ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค. ๋‰ด ํ—ค์ด๋ธ ์Šคํƒ€์ผ ํ”ผ์ž๋„ ์žˆ์–ด์š”!

๐Ÿญย ๋‹ค์–‘ํ•œ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

๊ฐ์ฒด๋งˆ์„์˜ ์ตœ์ฒจ๋‹จ ํ”ผ์ž ๊ฐ€๊ฒŒ๊ฐ€ SNS์—์„œ ํฐ ์ธ๊ธฐ๋ฅผ ๋Œ๊ฒŒ ๋˜๋‹ˆ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ž๊ธฐ ๋™๋„ค์—๋„ ์ตœ์ฒจ๋‹จ ํ”ผ์ž ๊ฐ€๊ฒŒ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ๋ฐ”๋žŒ์„ ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด์ œ ์ง€์ ์„ ๋‚ผ ๋•Œ๊ฐ€ ์™”๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์ž˜ ์จ์™”๋˜ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ์ง€์ ์—๋„ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ๋ฐœ์ „์‹œ์ผœ ๋ณด์ž. ๋จผ์ €, ๊ฐ ์ง€์ ๋งˆ๋‹ค ๊ทธ ์ง€์—ญ์˜ ํŠน์„ฑ๊ณผ ์ž…๋ง›์„ ๋ฐ˜์˜ํ•œ ๋‹ค์–‘ํ•œ ์Šคํƒ€์ผ์˜ ํ”ผ์ž(๋‰ด์š• ์Šคํƒ€์ผ, ์‹œ์นด๊ณ  ์Šคํƒ€์ผ, ์บ˜๋ฆฌํฌ๋‹ˆ์•„ ์Šคํƒ€์ผ ๋“ฑ)์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

Image

์ด๋ฏธ 1๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์•ž์—์„œ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.

  • SimplePizzaFactory๋ฅผ ์‚ญ์ œํ•˜๊ณ , 3๊ฐ€์ง€ ์„œ๋กœ ๋‹ค๋ฅธ ํŒฉํ† ๋ฆฌ(NYPizzaFactory, ChicagoPizzaFactory, CaliforniaPizzaFactory)๋ฅผ ๋งŒ๋“  ๋‹ค์Œ, PizzaStore์—์„œ ์ ๋‹นํ•œ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
1
2
const nyStore = new NYPizzaStore();
const chicagoStore = new ChicagoPizzaStore();

ํ•˜์ง€๋งŒ ์ง€์ ๋“ค์„ ์กฐ๊ธˆ ๋” ์ œ๋Œ€๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ง€์ ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํŒฉํ† ๋ฆฌ๋กœ ํ”ผ์ž๋ฅผ ๋งŒ๋“ค๊ธด ํ•˜๋Š”๋ฐ, ๊ตฝ๋Š” ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์ง„๋‹ค๊ฑฐ๋‚˜ ์ข…์ข… ํ”ผ์ž๋ฅผ ์ž๋ฅด๋Š” ๊ฒƒ์„ ๊นŒ๋จน๋Š” ์ผ์ด ์ƒ๊ธฐ๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ด์ƒํ•˜๊ฒŒ ์ƒ๊ธด ํ”ผ์ž ์ƒ์ž๋ฅผ ์“ฐ๋Š” ์ผ๋„ ์žˆ์—ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ํ”ผ์ž ์ œ์ž‘ ์ฝ”๋“œ ์ „์ฒด๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๋ฌผ๋ก  ๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค๋ฉด์„œ๋„ ์œ ์—ฐ์„ฑ์„ ์žƒ์–ด๋ฒ„๋ฆฌ๋ฉด ์•ˆ ๋œ๋‹ค.

SimplePizzaFactory๋ฅผ ๋งŒ๋“ค๊ธฐ ์ „์— ์ผ๋˜ ์ฝ”๋“œ์—๋Š” ํ”ผ์ž๋ฅผ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ๊ฐ€ PizzaStore์™€ ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธด ํ–ˆ์ง€๋งŒ ์œ ์—ฐ์„ฑ์ด ์ „ํ˜€ ์—†์—ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ”ผ์ž ๊ฐ€๊ฒŒ์™€ ํ”ผ์ž ๋งŒ๋“œ๋Š” ๊ณผ์ •์„ ํ•˜๋‚˜๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿญย ํ”ผ์ž ๊ฐ€๊ฒŒ ํ”„๋ ˆ์ž„์›Œํฌ ๋งŒ๋“ค๊ธฐ

์ด์ œ createPizza() ๋ฉ”์†Œ๋“œ๋ฅผ PizzaStore()์— ๋‹ค์‹œ ๋„ฃ๋„๋ก ํ•˜์ž. ํ•˜์ง€๋งŒ ๊ทธ ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ์„ ์–ธํ•˜๊ณ , ์ง€์—ญ๋ณ„ ์Šคํƒ€์ผ์— ๋งž๊ฒŒ PizzaStore์˜ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

1
2
3
4
PizzaStore (์ถ”์ƒ ํด๋ž˜์Šค)
 โ”œโ”€โ”€ NYPizzaStore           --> createPizza(): ๋‰ด์š• ์Šคํƒ€์ผ ํ”ผ์ž ์ƒ์„ฑ
 โ”œโ”€โ”€ ChicagoPizzaStore      --> createPizza(): ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ํ”ผ์ž ์ƒ์„ฑ
 โ””โ”€โ”€ CaliforniaPizzaStore   --> createPizza(): ์บ˜๋ฆฌํฌ๋‹ˆ์•„ ์Šคํƒ€์ผ ํ”ผ์ž ์ƒ์„ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class PizzaStore {
  orderPizza(type: string): Pizza {
    const pizza = this.createPizza(type);

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
  }

  protected abstract createPizza(type: string): Pizza;
}

์ด์ œ ๊ฐ ์ง€์ ์— ๋งž๋Š” ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ํ”ผ์ž์˜ ์Šคํƒ€์ผ์€ ๊ฐ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ฒฐ์ •ํ•œ๋‹ค.

๐Ÿญย ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ ์•Œ์•„๋ณด๊ธฐ

PizzaStore์˜ orderPizza() ๋ฉ”์†Œ๋“œ์— ์ด๋ฏธ ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์ด ์ž˜ ๊ฐ–์ถฐ์ ธ ์žˆ๋‹ค. ๋ชจ๋“  ์ง€์ ์—์„œ ์ด ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์„ ๋”ฐ๋ผ ์ฃผ๋ฌธ์ด ์ง„ํ–‰๋˜์–ด์—ฌ ํ•œ๋‹ค. ๊ฐ ์ง€์ ๋งˆ๋‹ค ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ํ”ผ์ž ์Šคํƒ€์ผ๋ฟ์ด๋‹ค. ๋‹ฌ๋ผ์ง€๋Š” ์ ์€ createPizza() ๋ฉ”์†Œ๋“œ์— ๋„ฃ๊ณ  ๊ทธ ๋ฉ”์†Œ๋“œ์—์„œ ํ•ด๋‹น ์Šคํƒ€์ผ์˜ ํ”ผ์ž๋ฅผ ๋งŒ๋“ค๋„๋ก ํ•  ๊ณ„ํš์ด๋‹ค. ์ด์ œ PizzaStore์˜ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ createPizza() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•˜์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class NYPizzaStore extends PizzaStore {
  protected createPizza(type: string): Pizza {
    if (type === "cheese") {
      return new NYStyleCheesePizza();
    } else if (type === "veggie") {
	    return new NYStyleVeggiePizza();
    } else if (type === "clam") {
	    return new NYStyleClamPizza();
    } else if (type === "pepperoni") {
	    return new NYStylePepperoniPizza();
    } else {
      throw new Error("ํ•ด๋‹น ํƒ€์ž… ์—†์Œ");
    }
  }
}

const nyStore = new NYPizzaStore();
nyStore.orderPizza("cheese"); 

๐Ÿญย ํ”ผ์ž ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋กœ ํ”ผ์ž ์ฃผ๋ฌธํ•˜๊ธฐ

์—๋‹จ: ๋‚˜๋Š” ๋‰ด์š• ์Šคํƒ€์ผ ํ”ผ์ž๊ฐ€ ์ข‹์•„. ์–‡๊ณ  ๋ฐ”์‚ญ๋ฐ”์‚ญํ•œ ๋นต ์œ„์— ์น˜์ฆˆ๋Š” ์•ฝ๊ฐ„๋งŒ ์˜ฌ๋ฆฌ๊ณ , ๋ง›์žˆ๋Š” ์†Œ์Šค๋ฅผ ๋ฟŒ๋ ค์•ผ ์ง„์งœ ํ”ผ์ž ๋ง›์ด ๋‚˜์ง€.

์กฐ์—˜: ๋‚˜๋Š” ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ํ”ผ์ž๊ฐ€ ์ข‹์€๋ฐ? ๋‘๊ป๊ณ  ๊นŠ์ˆ™ํ•œ ํฌ๋Ÿฌ์ŠคํŠธ์— ์น˜์ฆˆ๊ฐ€ ์™•์ฐฝ ๋“ค์–ด๊ฐ„ ๊ฒŒ ์ •๋ง ๋ง›์žˆ์ง€.

  • ์กฐ์—˜๊ณผ ์—๋‹จ ๋‘˜ ๋‹ค PizzaStore ์ธ์Šคํ„ด์Šค๋ฅผ ํ™•๋ณดํ•ด์•ผ ํ•œ๋‹ค. ์กฐ์—˜์€ ChicagoPizzaStore ์ธ์Šคํ„ด์Šค๋ฅผ, ์—๋‹จ์€ NYPizzaStore ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
1
2
const joelStore = new ChicagoPizzaStore();  // ์กฐ์—˜์€ ์‹œ์นด๊ณ  ์ง€์ 
const ethanStore = new NYPizzaStore();      // ์—๋‹จ์€ ๋‰ด์š• ์ง€์ 
  • PizzaStore๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋ฉด ๊ฐ๊ฐ orderPizza()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋•Œ ์ธ์ž๋ฅผ ์จ์„œ ์›ํ•˜๋Š” ๋ฉ”๋‰ด(์น˜์ฆˆ ํ”ผ์ž, ์•ผ์ฑ„ ํ”ผ์ž ๋“ฑ)์„ ์•Œ๋ ค ์ค˜์•ผ ํ•œ๋‹ค.
1
2
const joelPizza = joelStore.orderPizza("cheese");     // ์กฐ์—˜์€ ์น˜์ฆˆ ํ”ผ์ž ์ฃผ๋ฌธ
const ethanPizza = ethanStore.orderPizza("veggie");   // ์—๋‹จ์€ ์•ผ์ฑ„ ํ”ผ์ž ์ฃผ๋ฌธ
  • ํ”ผ์ž๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” createPizza() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š”๋ฐ, ์ด ๋ฉ”์†Œ๋“œ๋Š” PizzaStore ์„œ๋ธŒํด๋ž˜์Šค์ธ NYPizzaStore์™€ ChicagoPizzaStore์— ์ •์˜๋˜์–ด ์žˆ๋‹ค. ์–ด๋–ค ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์“ฐ๋“ ์ง€ Pizza ๊ฐ์ฒด๊ฐ€ orderPizza() ๋ฉ”์†Œ๋“œ๋กœ ๋ฆฌํ„ด๋œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
// ์˜ˆ์‹œ: ChicagoPizzaStore ๋‚ด๋ถ€
protected createPizza(type: string): Pizza {
  if (type === "cheese") return new ChicagoStyleCheesePizza();
  if (type === "veggie") return new ChicagoStyleVeggiePizza();
  throw new Error("์—†๋Š” ๋ฉ”๋‰ด์ž…๋‹ˆ๋‹ค");
}

// ์˜ˆ์‹œ: NYPizzaStore ๋‚ด๋ถ€
protected createPizza(type: string): Pizza {
  if (type === "cheese") return new NYStyleCheesePizza();
  if (type === "veggie") return new NYStyleVeggiePizza();
  throw new Error("์—†๋Š” ๋ฉ”๋‰ด์ž…๋‹ˆ๋‹ค");
}
  • orderPizza() ๋ฉ”์†Œ๋“œ๋Š” ์–ด๋˜ ์Šคํƒ€์ผ์˜ ํ”ผ์ž๊ฐ€ ๋งŒ๋“ค์–ด์กŒ๋Š”์ง€ ์ „ํ˜€ ์•Œ์ง€ ๋ชปํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ”ผ์ž๋ผ๋Š” ๊ฑด ์•Œ๊ณ  ์žˆ์–ด์„œ, ๊ทธ ํ”ผ์ž๋ฅผ ์ค€๋น„ํ•˜๊ณ , ๊ตฝ๊ณ , ์ž๋ฅด๊ณ , ํฌ์žฅํ•˜๋Š” ์ž‘์—…์„ ์™„๋ฃŒํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
// PizzaStore ์ถ”์ƒ ํด๋ž˜์Šค
orderPizza(type: string): Pizza {
  const pizza = this.createPizza(type);  // ์–ด๋–ค ์Šคํƒ€์ผ์ธ์ง€๋Š” ๋ชจ๋ฅด์ง€๋งŒ ํ”ผ์ž์ž„!

  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();

  return pizza;
}

๐Ÿญย Pizza ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ

์ด์ œ ํ”ผ์ž ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
abstract class Pizza {
  name: string = "";
  dough: string = "";
  sauce: string = "";
  toppings: string[] = [];

  prepare(): void {
    console.log(`\n๐Ÿ• ${this.name} ์ค€๋น„ ์ค‘`);
    console.log(`- ๋„์šฐ ๋ฐ˜์ฃฝ: ${this.dough}`);
    console.log(`- ์†Œ์Šค ์ถ”๊ฐ€: ${this.sauce}`);
    console.log(`- ํ† ํ•‘ ์ถ”๊ฐ€: ${this.toppings.join(", ")}`);
  }

  bake(): void {
    console.log("๐Ÿ”ฅ 175๋„์—์„œ 25๋ถ„ ๊ฐ„ ๊ตฝ๊ธฐ");
  }

  cut(): void {
    console.log("๐Ÿ”ช ํ”ผ์ž๋ฅผ ์‚ฌ์„ ์œผ๋กœ ์ž๋ฅด๊ธฐ");
  }

  box(): void {
    console.log("๐Ÿ“ฆ ์ƒ์ž์— ํ”ผ์ž ๋‹ด๊ธฐ");
  }

  getName(): string {
    return this.name;
  }
}

์ด์ œ ๊ตฌ์ƒ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๋‰ด์š• ์Šคํƒ€์ผ ์น˜์ฆˆ ํ”ผ์ž์™€ ์‹œ์นด๊ณ  ์Šคํƒ€์ผ์˜ ์น˜์ฆˆ ํ”ผ์ž๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class NYStyleCheesePizza extends Pizza {
  constructor() {
    super();
    this.name = "๋‰ด์š• ์Šคํƒ€์ผ ์†Œ์Šค์™€ ์น˜์ฆˆ ํ”ผ์ž";
    this.dough = "์”ฌ ํฌ๋Ÿฌ์ŠคํŠธ ๋„์šฐ";
    this.sauce = "๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค";
    this.toppings.push("์ž˜๊ฒŒ ์ฌ ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ");
  }
}

class ChicagoStyleCheesePizza extends Pizza {
  constructor() {
    super();
    this.name = "์‹œ์นด๊ณ  ์Šคํƒ€์ผ ๋”ฅ ๋””์‰ฌ ์น˜์ฆˆ ํ”ผ์ž";
    this.dough = "์•„์ฃผ ๋‘๊บผ์šด ํฌ๋Ÿฌ์ŠคํŠธ ๋„์šฐ";
    this.sauce = "ํ”Œ๋Ÿผ ํ† ๋งˆํ†  ์†Œ์Šค";
    this.toppings.push("์ž˜๊ฒŒ ์กฐ๊ฐ๋‚ธ ๋ชจ์งœ๋ ๋ผ ์น˜์ฆˆ");
  }

	// cut ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ
  cut(): void {
    console.log("๐Ÿ”ช ๋„ค๋ชจ๋‚œ ๋ชจ์–‘์œผ๋กœ ํ”ผ์ž ์ž๋ฅด๊ธฐ");
  }
}

๐Ÿญย ์ตœ์ฒจ๋‹จ ํ”ผ์ž ์ฝ”๋“œ ํ…Œ์ŠคํŠธ

1
2
3
4
5
6
7
8
9
10
11
// ๐Ÿ• ํ”ผ์ž ๊ฐ€๊ฒŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

const ethanStore = new NYPizzaStore();
const joelStore = new ChicagoPizzaStore();

const ethansPizza = ethanStore.orderPizza("cheese");
console.log(`์—๋‹จ์ด ์ฃผ๋ฌธํ•œ ${ethansPizza.getName()}`);

const joelsPizza = joelStore.orderPizza("cheese");
console.log(`์กฐ์—˜์ด ์ฃผ๋ฌธํ•œ ${joelsPizza.getName()}`);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
๐Ÿ• ๋‰ด์š• ์Šคํƒ€์ผ ์†Œ์Šค์™€ ์น˜์ฆˆ ํ”ผ์ž ์ค€๋น„ ์ค‘
- ๋„์šฐ ๋ฐ˜์ฃฝ: ์”ฌ ํฌ๋Ÿฌ์ŠคํŠธ ๋„์šฐ
- ์†Œ์Šค ์ถ”๊ฐ€: ๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค
- ํ† ํ•‘ ์ถ”๊ฐ€: ์ž˜๊ฒŒ ์ฌ ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ
๐Ÿ”ฅ 175๋„์—์„œ 25๋ถ„ ๊ฐ„ ๊ตฝ๊ธฐ
๐Ÿ”ช ํ”ผ์ž๋ฅผ ์‚ฌ์„ ์œผ๋กœ ์ž๋ฅด๊ธฐ
๐Ÿ“ฆ ์ƒ์ž์— ํ”ผ์ž ๋‹ด๊ธฐ
์—๋‹จ์ด ์ฃผ๋ฌธํ•œ ๋‰ด์š• ์Šคํƒ€์ผ ์†Œ์Šค์™€ ์น˜์ฆˆ ํ”ผ์ž

๐Ÿ• ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ๋”ฅ ๋””์‰ฌ ์น˜์ฆˆ ํ”ผ์ž
- ๋„์šฐ ๋ฐ˜์ฃฝ: ์•„์ฃผ ๋‘๊บผ์šด ํฌ๋Ÿฌ์ŠคํŠธ ๋„์šฐ
- ์†Œ์Šค ์ถ”๊ฐ€: ํ”Œ๋Ÿผ ํ† ๋งˆํ†  ์†Œ์Šค
- ํ† ํ•‘ ์ถ”๊ฐ€: ๋ชจ์งœ๋ ๋ผ ์น˜์ฆˆ ์Šฌ๋ผ์ด์Šค
๐Ÿ”ฅ 175๋„์—์„œ 25๋ถ„ ๊ฐ„ ๊ตฝ๊ธฐ
๐Ÿ”ช ํ”ผ์ž๋ฅผ ์‚ฌ์„ ์œผ๋กœ ์ž๋ฅด๊ธฐ
๐Ÿ“ฆ ์ƒ์ž์— ํ”ผ์ž ๋‹ด๊ธฐ
์กฐ์—˜์ด ์ฃผ๋ฌธํ•œ ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ๋”ฅ ๋””์‰ฌ ์น˜์ฆˆ ํ”ผ์ž

๐Ÿญย ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด ์‚ดํŽด๋ณด๊ธฐ

๋ชจ๋“  ํŒฉํ† ๋ฆฌ ํŒจํ„ด์€ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์บก์Аํ™”ํ•œ๋‹ค. ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์€ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€ ๊ฒฐ์ •ํ•จ์œผ๋กœ์จ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์บก์Аํ™”ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[๐Ÿ”จ ์ƒ์‚ฐ์ž ํด๋ž˜์Šค: PizzaStore]   โ† ์ถ”์ƒ ํด๋ž˜์Šค (Creator)
        โ”‚
        โ””โ”€โ”€ orderPizza() โ†’ ๊ณตํ†ต ์กฐ๋ฆฌ ํ”„๋กœ์„ธ์Šค
                 โ”‚
                 โ–ผ
        createPizza(type) โ† **์ถ”์ƒ ๋ฉ”์„œ๋“œ**
                 โ”‚
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚                         โ”‚
[NYPizzaStore]         [ChicagoPizzaStore]
  createPizza()           createPizza()
      โ”‚                       โ”‚
      โ–ผ                       โ–ผ

[๐Ÿ• ์ œํ’ˆ ํด๋ž˜์Šค: Pizza]    โ† ์ถ”์ƒ ํด๋ž˜์Šค (Product)
                 โ”‚
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚                         โ”‚
[NYStyleCheesePizza]  [ChicagoStyleCheesePizza]

๐Ÿ”จ ์ƒ์‚ฐ์ž ํด๋ž˜์Šค (Creator)

  • PizzaStore๊ฐ€ ์ƒ์‚ฐ์ž ํด๋ž˜์Šค
  • ํ•ต์‹ฌ ๋ฉ”์„œ๋“œ orderPizza()๋Š” ํ”ผ์ž๋ฅผ ์ฃผ๋ฌธ๋ฐ›๊ณ  ์กฐ๋ฆฌํ•˜๋Š” ๊ณตํ†ต ํ๋ฆ„์„ ๋‹ด๋‹น
  • ์–ด๋–ค ํ”ผ์ž๋ฅผ ๋งŒ๋“ค์ง€๋Š” ๋ชจ๋ฆ„ โ†’ createPizza()๋ผ๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ์œ„์ž„

๐Ÿ• ์ œํ’ˆ ํด๋ž˜์Šค (Product)

  • Pizza๋Š” ๋ชจ๋“  ํ”ผ์ž์˜ ๊ณตํ†ต์ ์ธ ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค
    • prepare(), bake(), cut(), box() ๋“ฑ์˜ ๋ฉ”์„œ๋“œ ํฌํ•จ

๐Ÿญย ๋ณ‘๋ ฌ ํด๋ž˜์Šค ๊ณ„์ธต๊ตฌ์กฐ ์•Œ์•„๋ณด๊ธฐ

๊ตฌ์ƒ ์ƒ์‚ฐ์ž๋ณ„๋กœ ์ˆ˜๋งŽ์€ ์ œํ’ˆ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์‹œ์นด๊ณ  ํ”ผ์ž ์ƒ์‚ฐ์ž๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ํ”ผ์ž๋ฅผ, ๋‰ด์š• ํ”ผ์ž ์ƒ์‚ฐ์ž๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋‰ด์š• ์Šคํƒ€์ผ ํ”ผ์ž๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ƒ์‚ฐ์ž ํด๋ž˜์Šค์™€ ๊ฑฐ๊ธฐ์— ๋Œ€์‘๋˜๋Š” ์ œํ’ˆ ํด๋ž˜์Šค๋Š” ๋ณ‘๋ ฌ ๊ณ„์ธต๊ตฌ์กฐ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 2๊ฐœ์˜ ๋ณ‘๋ ฌ ํด๋ž˜์Šค ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์—ฐ๊ด€๋˜๋Š”์ง€ ์•Œ์•„๋ณด์ž.

1
2
3
4
5
6
7
8
[๐Ÿ”จ ์ƒ์‚ฐ์ž ๊ณ„์ธต]                         [๐Ÿ• ์ œํ’ˆ ๊ณ„์ธต]
PizzaStore (์ถ”์ƒ ํด๋ž˜์Šค)          <-->     Pizza (์ถ”์ƒ ํด๋ž˜์Šค)
    โ”‚                                         โ”‚
    โ”œโ”€โ”€ NYPizzaStore                          โ”œโ”€โ”€ NYStyleCheesePizza
    โ”‚     โ””โ”€โ”€ createPizza("cheese") โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ””โ”€โ”€ NYStyleVeggiePizza
    โ”‚                                         โ”‚
    โ””โ”€โ”€ ChicagoPizzaStore                     โ”œโ”€โ”€ ChicagoStyleCheesePizza
          โ””โ”€โ”€ createPizza("cheese") โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ””โ”€โ”€ ChicagoStyleVeggiePizza
๊ณ„์ธตํด๋ž˜์Šค ์˜ˆ์‹œ์„ค๋ช…
์ƒ์‚ฐ์ž ๊ณ„์ธตPizzaStore, NYPizzaStore, ChicagoPizzaStoreํ”ผ์ž ์ฃผ๋ฌธ ํ๋ฆ„์„ ์ œ์–ด. ์–ด๋–ค ์Šคํƒ€์ผ์˜ ํ”ผ์ž๋ฅผ ๋งŒ๋“ค์ง€๋Š” ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๊ฒฐ์ •
์ œํ’ˆ ๊ณ„์ธตPizza, NYStyleCheesePizza, ChicagoStyleVeggiePizza์‹ค์ œ ํ”ผ์ž ํด๋ž˜์Šค. ์ง€์—ญ ์Šคํƒ€์ผ์— ๋”ฐ๋ผ ๊ตฌ์„ฑ ์š”์†Œ(์†Œ์Šค, ํ† ํ•‘ ๋“ฑ)๊ฐ€ ๋‹ค๋ฆ„
์—ฐ๊ด€createPizza() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋จ์ƒ์‚ฐ์ž๊ฐ€ ์–ด๋–ค ์ œํ’ˆ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€ ๊ฒฐ์ •ํ•จ

๐Ÿญย ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์˜ ์ •์˜

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ ๋‹ค. ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€๋Š” ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ฒฐ์ •ํ•œ๋‹ค. ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ๋งŒ๋“œ๋Š” ์ผ์„ ์„œ๋ธŒํด๋ž˜์Šค์— ๋งก๊ธฐ๊ฒŒ ๋œ๋‹ค.

๋‹ค๋ฅธ ํŒฉํ† ๋ฆฌ๋ฅผ ์“ธ ๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์œผ๋กœ ๊ตฌ์ƒ ํ˜•์‹ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…์„ ์บก์Аํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ‘์— ์žˆ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๋ณด๋ฉด, Creator ์ถ”์ƒ ํด๋ž˜์Šค์—์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฉ”์†Œ๋“œ, ์ฆ‰ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜์žˆ๋‹ค. Creator ์ถ”์ƒ ํด๋ž˜์Šค์— ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ๋Š” ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด ์ƒ์‚ฐ๋œ ์ œํ’ˆ์œผ๋กœ ํ•„์š”ํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ œํ’ˆ(๊ฐ์ฒด ์ธ์Šคํ„ด์Šค)์„ ๋งŒ๋“œ๋Š” ์ผ์€ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Image

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์—์„œ๋Š” ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€๋ฅผ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ฒฐ์ •ํ•œ๋‹ค.

์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์–ด๋–ค ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€๋ฅผ ๊ฒฐ์ •ํ•ด์„œ๊ฐ€ ์•„๋‹ˆ๋ผ, ์ƒ์‚ฐ์ž ํด๋ž˜์Šค๊ฐ€ ์‹ค์ œ ์ƒ์‚ฐ๋  ์ œํ’ˆ์„ ์ „ํ˜€ ๋ชจ๋ฅด๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋” ์ •ํ™•ํ•˜๊ฒŒ ๋งํ•˜๋ฉด, ์‚ฌ์šฉํ•˜๋Š” ์„œ๋ธŒํด๋ž˜์Šค์— ๋”ฐ๋ผ ์ƒ์‚ฐ๋˜๋Š” ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค.

๐Ÿ’ก ์ง„์งœ ์‰ฌ์šด ์˜ˆ๋น„ ๋น„์œ : ๋งˆ๋ฒ• ํ•™๊ต ๐Ÿง™

์ƒํ™ฉ:

  • ๋งˆ๋ฒ• ํ•™๊ต ๋ณธ๋ถ€์—๋Š” ์ฃผ๋ฌธ์„œ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ์ด ์žˆ๋‹ค. (orderScroll())
  • ์ฃผ๋ฌธ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ๋งˆ๋ฒ•์„œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. (createScroll())
  • ๊ทธ๋Ÿฐ๋ฐ ํ•™๊ต๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๋งˆ๋ฒ•์„œ ์Šคํƒ€์ผ์ด ๋‹ค๋ฅด๋‹ค.
1
2
3
4
5
6
7
8
abstract class MagicSchool {
  orderScroll(type: string) {
    const scroll = this.createScroll(type); // ์–ด๋–ค ์Šคํฌ๋กค์„ ๋งŒ๋“œ๋Š”์ง€๋Š” ๋ชจ๋ฅด์ง€๋งŒ
    scroll.prepare();                       // ๊ณตํ†ต ๋กœ์ง์€ ์—ฌ๊ธฐ์„œ ์ฒ˜๋ฆฌ
  }

  protected abstract createScroll(type: string): MagicScroll;
}

โ†’ createScroll()์ด ๋ฐ”๋กœ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ

โ†’ ์–ด๋–ค ์Šคํฌ๋กค์„ ๋งŒ๋“ค์ง€๋Š” HogwartsSchool, BeauxbatonsSchool ๊ฐ™์€ ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๊ฒฐ์ •

๐Ÿญย ์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™

๋””์ž์ธ ์›์น™
์ถ”์ƒํ™”๋œ ๊ฒƒ์— ์˜์กดํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ๊ตฌ์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“ ๋‹ค.

์ด ์›์น™๊ณผ โ€œ๊ตฌํ˜„๋ณด๋‹ค๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ๋งž์ถฐ์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค.โ€ ๋ผ๋Š” ์›์น™์ด ๋˜‘๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. ๋ฌผ๋ก  ๋น„์Šทํ•˜๊ธด ํ•˜์ง€๋งŒ ์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์—์„œ๋Š” ์ถ”์ƒํ™”๋ฅผ ๋” ๋งŽ์ด ๊ฐ•์กฐํ•œ๋‹ค. ์ด ์›์น™์—๋Š” ๊ณ ์ˆ˜์ค€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ ์š”์†Œ์— ์˜์กดํ•˜๋ฉด ์•ˆ ๋˜๋ฉฐ, ํ•ญ์ƒ ์ถ”์ƒํ™”์— ์˜์กดํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด ๋‹ด๊ฒจ ์žˆ๋‹ค.

์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์— ๋”ฐ๋ฅด๋ฉด, ๊ตฌ์ƒ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ๊ตฌ์ฒด์ ์ธ ๊ฒƒ์ด ์•„๋‹Œ ์ถ”์ƒ ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ฐ™์ด ์ถ”์ƒ์ ์ธ ๊ฒƒ์— ์˜์กดํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์ด ์›์น™์€ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ๊ณผ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์— ๋ชจ๋‘ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ์›์น™์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ?

1
2
3
4
5
[๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ: PizzaStore]
           โ”‚
           โ–ผ
  [NYStyleCheesePizza] [ChicagoStyleVeggiePizza] ...
      (์ €์ˆ˜์ค€ ๋ชจ๋“ˆ - ์‹ค์ œ ๊ตฌํ˜„์ฒด)

์‹ฌํ•˜๊ฒŒ ์˜์กด์ ์ธ PizzaStore์˜ ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ์ ์€ PizzaStore๊ฐ€ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ”ผ์ž์— ์˜์กดํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

1
2
3
4
5
6
7
8
        [๐Ÿฝ๏ธ PizzaStore (๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ)]
                 โ”‚
                 โ–ผ
 [๐Ÿ• Pizza (์ถ”์ƒ ์ œํ’ˆ ์ธํ„ฐํŽ˜์ด์Šค/์ถ”์ƒ ํด๋ž˜์Šค)]
                 โ–ฒ
                 โ”‚
  [NYStyleCheesePizza] [ChicagoStyleVeggiePizza] ...
      (์ €์ˆ˜์ค€ ๋ชจ๋“ˆ - ์‹ค์ œ ๊ตฌํ˜„์ฒด)

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์„ ์ ์šฉํ•˜๋ฉด ๊ณ ์ˆ˜์ค€ ๊ตฌ์„ฑ ์š”์†Œ์ธ PizzaStore์™€ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ ์š”์†Œ์ธ ํ”ผ์ž ๊ฐ์ฒด ๋ชจ๋‘๊ฐ€ ์ถ”์ƒ ํด๋ž˜์Šค์ธ Pizza์— ์˜์กดํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์—์„œ ๋ญ˜ ๋’ค์ง‘๋Š”๋‹ค๋Š” ๊ฑฐ์ฃ ?

์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์— โ€˜๋’ค์ง‘๊ธฐโ€™ ๋ผ๋Š” ๋ง์ด ๋“ค์–ด์žˆ๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ๋””์ž์ธ์„ ํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ๋Š” ๋ฐ˜๋Œ€๋กœ ๋’ค์ง‘์–ด์„œ ์ƒ๊ฐํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ๊ณผ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ๋‘˜ ๋‹ค ํ•˜๋‚˜์˜ ์ถ”์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•œ๋‹ค!

๋‹ค์Œ์˜ ๊ฐ€์ด๋“œ๋ผ์ธ์„ ๋”ฐ๋ฅด๋ฉด ์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์— ์œ„๋ฐฐ๋˜๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ๋””์ž์ธ์„ ํ”ผํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.

  • ๋ณ€์ˆ˜์— ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ €์žฅํ•˜์ง€ ๋ง™์‹œ๋‹ค.
    • new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ํŒฉํ† ๋ฆฌ๋ฅผ ์จ์„œ ๊ตฌ์ƒ ํด๋ž˜์Šค์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๋Š” ์ผ์„ ๋ฏธ๋ฆฌ ๋ฐฉ์ง€ํ•˜์ž.
  • ๊ตฌ์ƒ ํด๋ž˜์Šค์—์„œ ์œ ๋„๋œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€ ๋ง™์‹œ๋‹ค.
    • ๊ตฌ์ƒ ํด๋ž˜์Šค์—์„œ ์œ ๋„๋œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ํŠน์ • ๊ตฌ์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ถ”์ƒ ํด๋ž˜์Šค์ฒ˜๋Ÿผ ์ถ”์ƒํšŒ๋œ ๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
  • ๋ฒ ์ด์Šค ํด๋ž˜์Šค์— ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์ง€ ๋ง™์‹œ๋‹ค.
    • ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•œ๋‹ค๋ฉด ๋ฒ ์ด์Šค ํด๋ž˜์Šค๊ฐ€ ์ œ๋Œ€๋กœ ์ถ”์ƒํ™”๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ฒ ์ด์Šค ํด๋ž˜์Šค์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ๋Š” ๋ชจ๋“  ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋งŒ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿญย ์›์žฌ๋ฃŒ ์ข…๋ฅ˜ ์•Œ์•„๋ณด๊ธฐ

์ตœ๊ทผ ๋“ค์–ด์˜จ ์ •๋ณด์— ๋”ฐ๋ฅด๋ฉด, ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋„์ž…๋œ ์ดํ›„๋กœ ์ง€์ ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ •ํ•œ ์ ˆ์ฐจ๋Š” ์ž˜ ๋”ฐ๋ฅด๋Š”๋ฐ, ๋ช‡๋ช‡ ์ง€์ ์—์„œ ์ž์ž˜ํ•œ ์žฌ๋ฃŒ๋ฅผ ๋” ์‹ผ ์žฌ๋ฃŒ๋กœ ๋ฐ”๊ฟ”์„œ ๋งˆ์ง„์„ ๋†’์ด๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๋Ÿฐ ์ผ์ด ๊ณ„์†๋˜๋ฉด ๋ธŒ๋žœ๋“œ ์ด๋ฏธ์ง€์— ํฐ ํƒ€๊ฒฉ์ด ์˜ฌ ์ˆ˜๋„ ์žˆ๊ธฐ์— ๋ญ”๊ฐ€ ์กฐ์น˜๋ฅผ ์ทจํ•ด์•ผ ํ•œ๋‹ค.

์›์žฌ๋ฃŒ ํ’ˆ์งˆ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•

์›์žฌ๋ฃŒ๋ฅผ ์ƒ์‚ฐํ•˜๋Š” ๊ณต์žฅ์„ ๋งŒ๋“ค๊ณ  ์ง€์ ๊นŒ์ง€ ์žฌ๋ฃŒ๋ฅผ ๋ฐฐ๋‹ฌํ•˜๋ฉด ์–ด๋–จ๊นŒ? ํ•˜์ง€๋งŒ ์ง€์ ์ด ์„œ๋กœ ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ๊ณ , ๋‰ด์š•์˜ ๋ ˆ๋“œ ์†Œ์Šค์™€ ์‹œ์นด๊ณ ์˜ ๋ ˆ๋“œ ์†Œ์Šค๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋‰ด์š•๊ณผ ์‹œ์นด๊ณ ์— ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์žฌ๋ฃŒ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  • ๋‰ด์š• ์Šคํƒ€์ผ ํ”ผ์ž๋Š” ์–‡์€ ๋„์šฐ + ๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค + ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ
  • ์‹œ์นด๊ณ  ์Šคํƒ€์ผ ํ”ผ์ž๋Š” ๋‘๊บผ์šด ๋„์šฐ + ํ”Œ๋Ÿผ ํ† ๋งˆํ†  ์†Œ์Šค + ๋ชจ์งœ๋ ๋ผ ์น˜์ฆˆ

๐Ÿญย ์›์žฌ๋ฃŒ๊ตฐ์œผ๋กœ ๋ฌถ๊ธฐ

์‚ฌ๋กœ ๋‹ค๋ฅธ ์žฌ๋ฃŒ๋ฅผ ์ œ๊ณตํ•˜๋ ค๋ฉด ์›์žฌ๋ฃŒ๊ตฐ์„ ์ฒ˜๋ฆฌํ•  ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด ๋ด์•ผ ํ•œ๋‹ค. ๋ชจ๋“  ํ”ผ์ž๋Š” ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ(clams, sauceโ€ฆ)๋กœ ์ด๋ฃจ์–ด์ง€์ง€๋งŒ, ์ง€์—ญ๋งˆ๋‹ค ๊ตฌ์„ฑ ์š”์†Œ(frozenClams, freshClamsโ€ฆ)๋ฅผ ๋‹ค๋ฅธ ์ข…๋ฅ˜๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

  • ์‹œ์นด๊ณ 
    • FrozenClams, PlumTomatoSauce, MozzarellaCheeseโ€ฆ
  • ๋‰ด์š•
    • FreshClams, MarinaraSauce, ReggianoCheeseโ€ฆ

๐Ÿญย ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

์šฐ์„  ๋ชจ๋“  ์›์žฌ๋ฃŒ๋ฅผ ์ƒ์‚ฐํ•˜๋Š” ํŒฉํ† ๋ฆฌ์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
// ์ถ”์ƒ ์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ
interface PizzaIngredientFactory {
  createDough(): Dough;
  createSauce(): Sauce;
  createCheese(): Cheese;
  createVeggies(): Veggie[];
  createPepperoni(): Pepperoni;
  createClams(): Clams;
}

๐Ÿญย ๋‰ด์š• ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

์ด ํŒฉํ† ๋ฆฌ์—์„œ๋Š” ๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค, ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ, ์‹ ์„ ํ•œ ์กฐ๊ฐœ ๋“ฑ์„ ์ „๋ฌธ์ ์œผ๋กœ ์ƒ์‚ฐํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class NYPizzaIngredientFactory implements PizzaIngredientFactory {
  createDough(): Dough {
    return new ThickCrustDough();
  }

  createSauce(): Sauce {
    return new PlumTomatoSauce();
  }

  createCheese(): Cheese {
    return new MozzarellaCheese();
  }
  
  createVeggies(): Veggie[] {
    return [
      new Garlic(),
      new Onion(),
      new Mushroom(),
      new RedPepper(),
    ];
  }
  
  createPepperoni(): Pepperoni {
	  return new Slicedpepperoni();
  }
  
  createClams(): Clams {
	  return new FrozenClams();
  }
}

๐Ÿญย ์‹œ์นด๊ณ  ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
  createDough(): Dough {
    return new ThinCrustDough();
  }

  createSauce(): Sauce {
    return new MarinaraSauce();
  }

  createCheese(): Cheese {
    return new ReggianoCheese();
  }
  
  createVeggies(): Veggie[] {
    return [
      new BlackOlives(),
      new Spinach(),
      new EggPlant(),
    ];
  }
  
  createPepperoni(): Pepperoni {
	  return new Slicedpepperoni();
  }
  
  createClams(): Clams {
	  return new FreshClams();
  }
}

๐Ÿญย Pizza ํด๋ž˜์Šค ๋ณ€๊ฒฝํ•˜๊ธฐ

Pizza ํด๋ž˜์Šค๊ฐ€ ํŒฉํ† ๋ฆฌ์—์„œ ์ƒ์‚ฐํ•œ ์›์žฌ๋ฃŒ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๊ณ ์ณ๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
abstract class Pizza {
  name: string = "";
  dough: string = "";
  sauce: string = "";
  vegie: string[] = [];
  cheese: string = "";
  pepperoni: string = "";
  clam: string = "";


  // ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ์„ ์–ธ โ†’ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
  abstract prepare(): void;

  bake(): void {
    console.log("๐Ÿ”ฅ 175๋„์—์„œ 25๋ถ„ ๊ฐ„ ๊ตฝ๊ธฐ");
  }

  cut(): void {
    console.log("๐Ÿ”ช ํ”ผ์ž๋ฅผ ์‚ฌ์„ ์œผ๋กœ ์ž๋ฅด๊ธฐ");
  }

  box(): void {
    console.log("๐Ÿ“ฆ ์ƒ์ž์— ํ”ผ์ž ๋‹ด๊ธฐ");
  }

  getName(): string {
    return this.name;
  }
}

์น˜์ฆˆ ํ”ผ์ž ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

  • ํ”ผ์ž์˜ ์›์žฌ๋ฃŒ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒฉํ† ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๊ฐ ํ”ผ์ž ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž๋กœ๋ถ€ํ„ฐ ํŒฉํ† ๋ฆฌ๋ฅผ ์ „๋‹ฌ๋ฐ›๊ณ  ๊ทธ ํŒฉํ† ๋ฆฌ๋ฅผ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.
  • prepare() ๋ฉ”์†Œ๋“œ์—์„œ ์น˜์ฆˆ ํ”ผ์ž๋ฅผ ๋งŒ๋“œ๋Š” ๊ฐ ๋‹จ๊ณ„๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์žฌ๋ฃŒ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ํŒฉํ† ๋ฆฌ์— ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๋งŒ๋“ ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
class CheesePizza extends Pizza {
  constructor(private ingredientFactory: PizzaIngredientFactory) {
    super();
  }

  prepare(): void {
    console.log(`๐Ÿ• ์ค€๋น„ ์ค‘ ${this.name}`);
    this.dough = this.ingredientFactory.createDough();
    this.sauce = this.ingredientFactory.createSauce();
    this.cheese = this.ingredientFactory.createCheese();
  }
}

๐Ÿญย ์˜ฌ๋ฐ”๋ฅธ ์žฌ๋ฃŒ ๊ณต์žฅ ์‚ฌ์šฉํ•˜๊ธฐ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class NYPizzaStore extends PizzaStore {
  protected createPizza(type: string): Pizza {
    // ๋‰ด์š• ์ง€์ ์—๋Š” ๋‰ด์š• ํ”ผ์ž ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ๋ฅผ ์ „๋‹ฌํ•ด ์ค˜์•ผ ํ•œ๋‹ค.
    // ํ•„์š”ํ•œ ์žฌ๋ฃŒ๋Š” ์ด ํŒฉํ† ๋ฆฌ์—์„œ ๊ณต๊ธ‰ํ•œ๋‹ค.
    const ingredientFactory = new NYPizzaIngredientFactory();

    if (type === "cheese") {
      const pizza = new CheesePizza(ingredientFactory);
      pizza.setName("๋‰ด์š• ์Šคํƒ€์ผ ์น˜์ฆˆ ํ”ผ์ž");
      return pizza;
    }
    .
    .
    .
  }
}

1
2
3
4
5
6
7
[PizzaStore]                 [Pizza]
     โ–ฒ                           โ–ฒ
[NYPizzaStore]             [CheesePizza]
     โ”‚                           โ–ฒ
     โ–ผ                           โ”‚
[NYPizzaIngredientFactory] โ”€โ”€โ”€โ”€โ”€โ”˜
      โ””โ”€โ”€ createDough(), createSauce(), createCheese()

๐Ÿญย ์ƒˆ๋กœ์šด ์ฝ”๋“œ๋กœ ๋˜ ํ”ผ์ž ์ฃผ๋ฌธํ•˜๊ธฐ

์—๋‹จ: ๋‚œ ์—ฌ์ „ํžˆ ๋‰ด์š• ์Šคํƒ€์ผ์ด ์ข‹๋”๋ผ

์กฐ์—˜: ๋‚œ ๊ทธ๋ƒฅ ์‹œ์นด๊ณ  ์Šคํƒ€์ผ๋กœ ๋จน์„๋ž˜

  • ์ฃผ๋ฌธ ์ฒซ ๋‹จ๊ณ„๋Š” ๋ฐ”๋€Œ์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์šฐ์„  ๊ฐ๊ฐ์˜ ํ”ผ์ž ๊ฐ€๊ฒŒ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
1
2
const ethanStore = new NYPizzaStore(); // ์—๋‹จ: ๋‰ด์š• ์Šคํƒ€์ผ
const joelStore = new ChicagoPizzaStore(); // ์กฐ์—˜: ์‹œ์นด๊ณ  ์Šคํƒ€์ผ
  • ๊ฐ€๊ฒŒ๊ฐ€ ์ค€๋น„๋์œผ๋ฏ€๋กœ ์ฃผ๋ฌธํ•œ๋‹ค.
1
2
const ethansPizza = ethanStore.orderPizza("cheese");
const joelsPizza = joelStore.orderPizza("cheese");
  • orderPizza() ๋ฉ”์†Œ๋“œ๋Š” ์ผ๋‹จ createPizza() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
abstract class PizzaStore {
  orderPizza(type: string): Pizza {
    const pizza = this.createPizza(type); // โ† ์—ฌ๊ธฐ๊ฐ€ ํ•ต์‹ฌ!
    pizza.prepare();                      // ์ดํ›„๋Š” ๊ณตํ†ต ๋กœ์ง
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
  }

  protected abstract createPizza(type: string): Pizza;
}
  • ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ๋‹ฌ๋ผ์ง„๋‹ค. createPizza() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์›์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ๊ฐ€ ๋Œ์•„๊ฐ€๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
class NYPizzaStore extends PizzaStore {
  protected createPizza(type: string): Pizza {
    const ingredientFactory = new NYPizzaIngredientFactory();

    if (type === "cheese") {
      const pizza = new CheesePizza(ingredientFactory);
      pizza.setName("๋‰ด์š• ์Šคํƒ€์ผ ์น˜์ฆˆ ํ”ผ์ž");
      return pizza;
    }

    throw new Error("ํ•ด๋‹น ๋ฉ”๋‰ด ์—†์Œ");
  }
}
  • ์ด์ œ ํ”ผ์ž๋ฅผ ์ค€๋น„ํ•œ๋‹ค. prepare() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํŒฉํ† ๋ฆฌ์— ์›์žฌ๋ฃŒ ์ฃผ๋ฌธ์ด ๋“ค์–ด๊ฐ„๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
class CheesePizza extends Pizza {
  constructor(private ingredientFactory: PizzaIngredientFactory) {
    super();
    this.setName("์น˜์ฆˆ ํ”ผ์ž");
  }

  prepare(): void {
    console.log(`๐Ÿ• ${this.name} ์ค€๋น„ ์ค‘`);
    this.dough = this.ingredientFactory.createDough();
    this.sauce = this.ingredientFactory.createSauce();
    this.cheese = this.ingredientFactory.createCheese();
  }
}
  • ํ”ผ์ž ์ค€๋น„ ์™„๋ฃŒ
1
2
3
pizza.bake(); // "๐Ÿ”ฅ 175๋„์—์„œ 25๋ถ„ ๊ฐ„ ๊ตฝ๊ธฐ"
pizza.cut();  // "๐Ÿ”ช ํ”ผ์ž๋ฅผ ์‚ฌ์„ ์œผ๋กœ ์ž๋ฅด๊ธฐ" ๋˜๋Š” ๋„ค๋ชจ ์ž๋ฅด๊ธฐ
pizza.box();  // "๐Ÿ“ฆ ์ƒ์ž์— ํ”ผ์ž ๋‹ด๊ธฐ"

๐Ÿญย ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์˜ ์ •์˜

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด(Abstract Factory Pattern)์€ ๊ตฌ์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•˜์ง€ ์•Š๊ณ ๋„ ์„œ๋กœ ์—ฐ๊ด€๋˜๊ฑฐ๋‚˜ ์˜์กด์ ์ธ ๊ฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ง„ ์ œํ’ˆ๊ตฐ์„ ์ƒ์‚ฐํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๊ตฌ์ƒ ํด๋ž˜์Šค๋Š” ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๋งŒ๋“ ๋‹ค.

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ถ”์ƒ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ผ๋ จ์˜ ์ œํ’ˆ์„ ๊ณต๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, ์‹ค์ œ๋กœ ์–ด๋–ค ์ œํ’ˆ์ด ์ƒ์‚ฐ๋˜๋Š”์ง€๋Š” ์ „ํ˜€ ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ์™€ ํŒฉํ† ๋ฆฌ์—์„œ ์ƒ์‚ฐ๋˜๋Š” ์ œํ’ˆ์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ… ์•„์ฃผ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด?

โ€œ์„œ๋กœ ๊ด€๋ จ๋œ ๊ฐ์ฒด๋“ค์„ ํ•œ๊บผ๋ฒˆ์— ์ผ๊ด€๋œ ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํŒจํ„ดโ€

๐Ÿ• ํ”ผ์ž ์˜ˆ์‹œ๋กœ ์„ค๋ช…ํ•˜๋ฉด?

๋‰ด์š• ํ”ผ์ž๋Š” ์–‡์€ ๋„์šฐ + ๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค + ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ

1
์‹œ์นด๊ณ  ํ”ผ์ž๋Š” ๋‘๊บผ์šด ๋„์šฐ + ํ”Œ๋Ÿผ ํ† ๋งˆํ†  ์†Œ์Šค + ๋ชจ์งœ๋ ๋ผ ์น˜์ฆˆ

๐Ÿ• ์Šคํƒ€์ผ์ด ๋‹ค๋ฅด๋ฉด ์žฌ๋ฃŒ ์ „์ฒด๊ฐ€ ์„ธํŠธ๋กœ ๋ฐ”๋€Œ์–ด์•ผ ํ•จ

โ†’ ๊ทธ๋ž˜์„œ ์žฌ๋ฃŒ๋ฅผ ํ•œ ๋ฒˆ์— ๋ฌถ์–ด์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํŒฉํ† ๋ฆฌ๊ฐ€ ํ•„์š”

โ†’ ๊ทธ๊ฒŒ ๋ฐ”๋กœ ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   [๐Ÿ‘จโ€๐Ÿณ PizzaIngredientFactory]        โ† ์ถ”์ƒ ํŒฉํ† ๋ฆฌ
    โ”œโ”€ createDough(): Dough
    โ”œโ”€ createSauce(): Sauce
    โ””โ”€ createCheese(): Cheese

       โ–ฒ                         โ–ฒ
       โ”‚                         โ”‚
[NYPizzaIngredientFactory] [ChicagoPizzaIngredientFactory]
     โ””โ”€ ์–‡์€ ๋„์šฐ                 โ””โ”€ ๋‘๊บผ์šด ๋„์šฐ
     โ””โ”€ ๋งˆ๋ฆฌ๋‚˜๋ผ ์†Œ์Šค             โ””โ”€ ํ”Œ๋Ÿผ ํ† ๋งˆํ†  ์†Œ์Šค
     โ””โ”€ ๋ ˆ์ง€์•„๋…ธ ์น˜์ฆˆ             โ””โ”€ ๋ชจ์งœ๋ ๋ผ ์น˜์ฆˆ

               โ†“ ์‚ฌ์šฉ
         [๐Ÿ• CheesePizza]
          โ””โ”€ prepare()์—์„œ ์žฌ๋ฃŒ ์ƒ์„ฑ ์š”์ฒญ

๐Ÿญย ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด๊ณผ ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด

๊ตฌ๋ถ„ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ์ถ”์ƒ ํŒฉํ† ๋ฆฌ
๋ชฉ์ ํ•œ ๊ฐ€์ง€ ์ œํ’ˆ์„ ์ƒ์„ฑ์—ฌ๋Ÿฌ ๊ด€๋ จ๋œ ์ œํ’ˆ๊ตฐ ์ƒ์„ฑ
ํ™•์žฅ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์ œํ’ˆ ๊ฒฐ์ •์ œํ’ˆ๊ตฐ ์ „์ฒด๋ฅผ ํŒฉํ† ๋ฆฌ๋กœ ๋Œ€์ฒด
์˜ˆ์‹œํ”ผ์ž ์ข…๋ฅ˜๋งŒ ๋‹ค๋ฆ„ํ”ผ์ž ์žฌ๋ฃŒ๊นŒ์ง€ ์ง€์—ญ๋ณ„๋กœ ๋‹ค๋ฆ„
๊ตฌ์กฐ์ƒ์† ๊ธฐ๋ฐ˜๊ตฌ์„ฑ ๊ธฐ๋ฐ˜ (์ธํ„ฐํŽ˜์ด์Šค ์ „๋‹ฌ)

โœจ ์ •๋ฆฌ

  • ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์€ โ€œ์ œํ’ˆ๊ตฐ ์ „์ฒด๋ฅผ ํ•œ ๋ฒˆ์— ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œโ€ ์œ ์šฉํ•จ
  • Pizza ํด๋ž˜์Šค๋Š” ์žฌ๋ฃŒ๋ฅผ ์ง์ ‘ new ํ•˜์ง€ ์•Š์Œ โ†’ ์žฌ๋ฃŒ ํŒฉํ† ๋ฆฌ์— ์œ„์ž„
  • ์ง€์—ญ๋ณ„ ์žฌ๋ฃŒ๊ฐ€ ๋‹ค๋ฅด๋ฉด, ์ง€์—ญ๋ณ„ ํŒฉํ† ๋ฆฌ๋งŒ ๋ฐ”๊พธ๋ฉด ๋จ
  • ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด, ์ œํ’ˆ๊ตฐ ๊ต์ฒด ๊ฐ€๋Šฅ (OCP ์œ ์ง€)
This post is licensed under CC BY 4.0 by the author.