๐จ 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"๊ฐ์ ๋ฌธ์์ด๋ก ํผ์๋ฅผ ์ฃผ๋ฌธํ๋ฉด,- SimplePizzaFactory์๊ฒ ํผ์ ๋ง๋ค์ด๋ฌ๋ผ๊ณ ์์ฒญํจ
- ๋ฐ์ ํผ์ ๊ฐ์ฒด๋ฅผ ์๋ง์ ์์๋๋ก ์ฒ๋ฆฌํจ (์ค๋น โ ๊ตฝ๊ธฐ โ ์๋ฅด๊ธฐ โ ํฌ์ฅ)
๐ญย โ๊ฐ๋จํ ํฉํ ๋ฆฌโ์ ์ ์
๊ฐ๋จํ ํฉํ ๋ฆฌ(Simple Factory)๋ ๋์์ธ ํจํด์ด๋ผ๊ธฐ ๋ณด๋ค๋ ํ๋ก๊ทธ๋๋ฐ์์ ์์ฃผ ์ฐ์ด๋ ๊ด์ฉ๊ตฌ์ ๊ฐ๊น๋ค. ๊ฐ๋จํ ํฉํ ๋ฆฌ๋ฅผ โํฉํ ๋ฆฌ ํจํดโ์ด๋ผ๊ณ ๋ถ๋ฅด๋ ์ฌ๋๋ค๋ ์์ง๋ง, ์ ํํ๊ฒ ํจํด์ ์๋๋ค. ๊ฐ๋จํ ํฉํ ๋ฆฌ๋ฅผ ์ ์ฐ๋์ง ์์๋ณด์.
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ํด์ ๋ง๋ค์ด๋
๐ ์ ์ฒด ํ๋ฆ ์์ฝ
PizzaStore์์"cheese"๋ผ๋ ์ฃผ๋ฌธ์ด ๋ค์ด์ดSimplePizzaFactory.createPizza("cheese")ํธ์ถ- ํฉํ ๋ฆฌ๋
new CheesePizza()๋ก ํผ์ ๊ฐ์ฒด ์์ฑ PizzaStore๋ ๋ฐ์ ํผ์์ ๋ํดprepare(),bake()๋ฑ ์ฒ๋ฆฌ- ์๋์๊ฒ ๋ฐํ ๐
Kohi์ ๋ง:
๊ทธ๋ผ ๋ด๊ฐ ์๊น๊น์ง ํ ๊ฒ ๋ชจ๋ ๋ค ๊ฐ๋จํ ํฉํ ๋ฆฌ์๋ค๊ณ โฆ?
ChatGPT์ ๋ง:
๐ ์ ํํด! ๋ค๊ฐ ์ง๊ธ๊น์ง ๋ง๋ ๊ตฌ์กฐ๋ ์ ํ์ ์ธ โ๊ฐ๋จํ ํฉํ ๋ฆฌ(Simple Factory)โ ํจํด์ด์ผ!
PizzaStore์์Pizza๋ฅผ ์ง์ new๋ก ๋ง๋ค๋ ๊ฑธSimplePizzaFactory๋ก ๊ฐ์ฒด ์์ฑ ์ฑ ์์ ๋ถ๋ฆฌํ๊ณPizzaStore๋ ์ด์ โํผ์๋ฅผ ์ฃผ๋ฌธ๋ฐ๊ณ ์ฒ๋ฆฌโํ๋ ์ญํ ๋ง ํ๊ฒ ๋จ
๐ ์ด ๊ตฌ์กฐ๊ฐ ๋ฐ๋ก ๊ฐ๋จํ ํฉํ ๋ฆฌ ํจํด์ ๋ํ์ ์ธ ํํ
๐ง ๊ทธ๋ฐ๋ฐ ์ โํจํดโ์ด ์๋๋ผ โ๊ด์ฉ๊ตฌ(idiom)โ๋ผ๊ณ ํ ๊น?
- GoF(๋์์ธ ํจํด์ ๋ฐ์ด๋ธ)์ ๋์ค๋ 23๊ฐ์ง ๋์์ธ ํจํด์๋ Simple Factory๋ ์์
- ๊ทธ ๋์ ์ด๊ฑด ์์ฃผ ์ฐ์ด๋ ์ ์ฉํ ์ค๊ณ ์ต๊ด์ด๋ผ์, ๋ง์ ์ฌ๋๋ค์ด โํจํด์ฒ๋ผโ ์ฌ์ฉํ์ง๋ง, ์๋ฐํ ๋งํ๋ฉด ๋์์ธ ํจํด์ ์๋
๊ฐ์ฒด ๊ตฌ์ฑ์ ํ์ฉํ๋ฉด ํ๋์ ์คํํ ๋ ๊ตฌํ๋ ๊ฐ์ฒด๋ฅผ ๋์ ์ผ๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค. PizzaStore์์๋ ๊ทธ ๋ฐฉ๋ฒ์ ์ธ ์ ์์๊น์? ํฉํ ๋ฆฌ ํด๋์ค์์ ์ด๋ค ๋ถ๋ถ์ ๋ง์๋๋ก ๋ฐ๊ฟ ์ ์์๊น์?
์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ง๋ง, ์ฐ๋ฆฌ๋ ๋ด์ ์คํ์ผ, ์์นด๊ณ ์คํ์ผ, ์บ๋ฆฌํฌ๋์ ์คํ์ผ ํผ์๋ฅผ ๋ ์ฌ๋ ธ์ต๋๋ค. ๋ด ํค์ด๋ธ ์คํ์ผ ํผ์๋ ์์ด์!
๐ญย ๋ค์ํ ํฉํ ๋ฆฌ ๋ง๋ค๊ธฐ
๊ฐ์ฒด๋ง์์ ์ต์ฒจ๋จ ํผ์ ๊ฐ๊ฒ๊ฐ SNS์์ ํฐ ์ธ๊ธฐ๋ฅผ ๋๊ฒ ๋๋ ๋ง์ ์ฌ๋๋ค์ด ์๊ธฐ ๋๋ค์๋ ์ต์ฒจ๋จ ํผ์ ๊ฐ๊ฒ๊ฐ ์์ผ๋ฉด ์ข๊ฒ ๋ค๋ ๋ฐ๋์ ๊ฐ์ง๊ฒ ๋์๋ค. ์ด์ ์ง์ ์ ๋ผ ๋๊ฐ ์๋ค. ์ง๊ธ๊น์ง ์ ์จ์๋ ์ฝ๋๋ฅผ ๋ค๋ฅธ ์ง์ ์๋ ์ธ ์ ์๋๋ก ๋ฐ์ ์์ผ ๋ณด์. ๋จผ์ , ๊ฐ ์ง์ ๋ง๋ค ๊ทธ ์ง์ญ์ ํน์ฑ๊ณผ ์ ๋ง์ ๋ฐ์ํ ๋ค์ํ ์คํ์ผ์ ํผ์(๋ด์ ์คํ์ผ, ์์นด๊ณ ์คํ์ผ, ์บ๋ฆฌํฌ๋์ ์คํ์ผ ๋ฑ)์ ๋ง๋ค์ด์ผ ํ๋ค.
์ด๋ฏธ 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 ์ถ์ ํด๋์ค์ ๊ตฌํ๋์ด ์๋ ๋ค๋ฅธ ๋ฉ์๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋์ ์ํด ์์ฐ๋ ์ ํ์ผ๋ก ํ์ํ ์์ ์ ์ฒ๋ฆฌํ๋ค. ํ์ง๋ง ์ค์ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ๊ตฌํํ๊ณ ์ ํ(๊ฐ์ฒด ์ธ์คํด์ค)์ ๋ง๋๋ ์ผ์ ์๋ธํด๋์ค์์๋ง ํ ์ ์๋ค.
ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์์๋ ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง๋ฅผ ์๋ธํด๋์ค์์ ๊ฒฐ์ ํ๋ค.
์๋ธํด๋์ค์์ ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง๋ฅผ ๊ฒฐ์ ํด์๊ฐ ์๋๋ผ, ์์ฐ์ ํด๋์ค๊ฐ ์ค์ ์์ฐ๋ ์ ํ์ ์ ํ ๋ชจ๋ฅด๋ ์ํ๋ก ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์ด๋ค. ๋ ์ ํํ๊ฒ ๋งํ๋ฉด, ์ฌ์ฉํ๋ ์๋ธํด๋์ค์ ๋ฐ๋ผ ์์ฐ๋๋ ๊ฐ์ฒด ์ธ์คํด์ค๊ฐ ๊ฒฐ์ ๋๋ค.
๐ก ์ง์ง ์ฌ์ด ์๋น ๋น์ : ๋ง๋ฒ ํ๊ต ๐ง
์ํฉ:
- ๋ง๋ฒ ํ๊ต ๋ณธ๋ถ์๋
์ฃผ๋ฌธ์ ์ฒ๋ฆฌ ์์คํ ์ด ์๋ค. (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 ์ ์ง)


