์ ํฌ์คํ ([ํ์ ์คํฌ๋ฆฝํธ] ๊ฐ์ฒด์งํฅ์ ๊ฝ composition(๋ถ์ : ์์์ ๋ฌธ์ ์ ) — My dev Note๐ (tistory.com))๊ณผ ์ด์ด์ง๋๋ค
์ ํฌ์คํ ์์ฝ : ์ปดํฌ์ง์ ์ ํตํด์(3~4๋จ๊ณ๋ฅผ ๋์ด๊ฐ๋ ์์ ์์ง ๊ด๊ณ๋ฅผ ํด์) ์์์ 2๋จ๊ณ ์ด์์ผ๋ก ์ฌ์ฉํ์ง ์๊ณ ๋ ํ๋์ ํด๋์ค์ ์ฌ๋ฌ๊ฐ์ง ๋ถํ ํด๋์ค๋ฅผ ์ฃผ์
ํค๋ฉ ํฌ์คํ ์์ฝ :
"๊ฐ๋ ฅํ interface์ composition์ ๋ณตํฉ๊ฐ๋ ์ด ๋๋ ์ ๋ต ํจํด์ ์ด์ฉํ์ฌ ํ๋ฆฌํฐ ๋์ ์ฝ๋๋ฅผ ์์ฐํ์"
์ธํฐํ์ด์ค๋ก ํ์ฌ๊ธ ํ์ํ ๊ธฐ๋ฅ๋ค์ ๊ตฌํํ ๊ฐ๊ฐ ํด๋์ค๋ค์ ์์ฑ, ๋ถํ์ผ๋ก ์ ๋ฌํ์ฌ
์ฌ์ฉ์๋ ์ํ ๋๋ง๋ค ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋ค๋ฅธ ๋ถํ( ํด๋์ค)๋ค์ ๋ผ์๋ฃ์ ์๋ก์ด ํด๋์ค๋ฅผ ์ฐ์ด๋ผ ์๋ ์๋ค.
์ํ๋ ์ฉ๋์ ๋ง๊ฒ ํด๋์ค๋ค์ ์ฝ๋ ์ฌ์ฌ์ฉํ๋ฉด์ ๋ง๋ค์ด๋ผ ์ ์๊ฒ ๋๋ค!
์ฌ๋ฌ๊ฐ์ง ๋ถํ๋ค์ ํ์ฅ์ฑ์๊ฒ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉ, ์กฐ๋ฆฝํด๋๊ฐ๋ฉด์ ์ํ๋ ๋งํผ ๋ค์ํ ํํ์ ์ค๋ธ์ ํธ๋ค์ ๊ณ์ ๋ง๋ค ์ ์๋ค.(๋๋ฌด๋ ์ฌ์ด ์ ์ง๋ณด์)
composition์ผ๋ก ์์์ ๋จ๊ณ๋ฅผ 1๋จ๊ณ๋ก ๋ฎ์ถ๋๋ผ๋, ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ๋ฎ๋ค.
ํด๋์ค๋ค ๊ฐ์ ์์ฌ์ํต, ์ํธ ์์ฉ ํ๋ ๊ฒฝ์ฐ์ ํด๋์ค ์์ ์ ๋ ธ์ถํ๋ ๊ฒ์ด ์๋๋ผ ๊ณ์ฝ์์ ์ ํ ๊ณ์ฝ์ ์๊ฑฐํด์ ์์ฌ์ํต ํ๋ ๊ฒ์ด ์กฐ๊ธ ๋ ํ์ฅ๊ฐ๋ฅํ๊ณ ์ ์ฐํ ์ฝ๋๋ฅผ ๋ง๋๋๋ฐ ์ข์ ๊ฒ์ด๋ค.
์ฌ๊ธฐ์ ๊ณ์ฝ์๊ฐ ๋ฐ๋ก ์ธํฐํ์ด์ค๊ฐ ๋๋ค. ์ด๊ฒ์ด ํด๋์ค ๋์ปคํ๋ง์ ๋จ์ด์ด๋ค.
์ปดํฌ์ง์ ์ผ๋ก ํด๋์ค๊ฐ ์ปคํ๋ง์ด ๊ฐํ ์ฝ๋๋ฅผ
์ธํฐํ์ด์ค๋ฅผ ํตํด์ ํด๋์ค ๊ฐ์ ์์ฌ์ํต, ์ํธ์์ฉ ํ ์ ์๋๋ก ํ์ฌ
๋์ปคํ๋ง๋ ์ฝ๋๋ก ์์ ํด๋ณด๋ ํฌ์คํ
<์๋ ์ฝ๋ ์์ฝ>
(์ปดํฌ์ง์ ๋ฐฉ์์ ๋์ ํ์ฌ ์์์ด 1๋จ๊ณ๋ก ์ ์ง๋์์ง๋ง ํด๋์ค ๊ฐ ๊ฒฐํฉ๋๊ฐ ๋๋ค๋ ๋ฌธ์ ์ ์ด ์๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ ๊ฐ๋ ฅํ ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด์ ํด๋์ค ๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถฐ๋ณด๋๋ก ํ๋ค.)
์ปคํผ๋จธ์ ํด๋์ค์,
์ปคํผ๋จธ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ์นดํ๋ผ๋ผ๋จธ์ ,
์ปคํผ๋จธ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ์๊ธ์ปคํผ๋จธ์ ,
์ปคํผ๋จธ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ์๊ธ์นดํ๋ผ๋ด๋จธ์ .
์ํธ ๋ฏน์ ํด๋์ค๊ฐ ์ปดํฌ์ง์ ์ด ๋์ด ์๊ธ์ปคํผ๋จธ์ ๊ณผ ์๊ธ์นดํ๋ผ๋ผ๋จธ์ ์ ์๊ธ์ด ์ถ๊ฐ๋๊ณ ,
๋ฐํฌ ์คํ ํด๋์ค๊ฐ ์ปดํฌ์ง์ ์ด ๋์ด ์นดํ๋ผ๋ผ๋จธ์ ๊ณผ ์๊ธ์นดํ๋ผ๋ผ๋จธ์ ์ ์ฐ์ ํผ์ด ์ถ๊ฐ๋๋ค.
// //์ปคํผ๋จธ์ ๋ง๋ค๊ธฐ
type CoffeeCup = {
orderShot: number;
hasMilk?: boolean;
hasSalt?: boolean;
};
interface CoffeeMaker {
makeCoffee(shots: number): CoffeeCup;
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
protected static ONE_SHOT_CAPSULE: number = 3;
protected static ONE_CUP_WATER: number = 10;
static makeMachine(beans: number, water: number): CoffeMachine {
return new CoffeMachine(beans, water);
}
public constructor(
protected capsule: number = 3,
protected water: number = 10
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
return this.extract(orderShot);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
// CoffeMachine ํด๋์ค๋ฅผ ์์๋ฐ์ CafeLatteMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class CafeLatteMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private milkFrother: CheapMilkSteamer
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์ ์๋น, ๋ฌผ ์๋น, ๋ฌผ ๊ฐ์ด ๋ค ๋๋๊ณ ์์ฑ๋ ์ปคํผ๊ฐ ๋ฐํ
return this.milkFrother.addMilkform(coffee);
}
}
// CoffeMachine ํด๋์ค ๋ฅผ ์์๋ฐ์ saltCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltMixer
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
return this.saltTopping.addSalt(coffee);
}
}
// ๋ง๋ค๊ณ ์ถ์๋ saltCafeLatteCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCafeLatteCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltMixer,
private milkFrother: CheapMilkSteamer
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
const saltAdded = this.saltTopping.addSalt(coffee);
return this.milkFrother.addMilkform(saltAdded);
}
}
const machines: CoffeeMaker[] = [
new CoffeMachine(25, 25),
new CafeLatteMachine(15, 25, new CheapMilkSteamer()),
new saltCoffeeMachine(5, 10, new SaltMixer()),
new saltCafeLatteCoffeeMachine(
5,
10,
new SaltMixer(),
new CheapMilkSteamer()
),
];
machines.forEach((machine) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(machine.makeCoffee(1));
});
์ด๋ ๊ฒ ์ฝ์์ฐฝ์ ์ ๋ ฅํ๋ฉด
const cheapMilkSteamer = new CheapMilkSteamer();
const saltMixer = new SaltMixer();
const saltCoffeeMaker = new saltCoffeeMachine(100, 100, saltMixer);
const saltCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const latteMaker = new CafeLatteMachine(100, 100, cheapMilkSteamer);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
saltCoffeeMaker,
saltCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
<์ถ๋ ฅ๊ฒฐ๊ณผ>
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
{ orderShot: 1, hasMilk: false, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
๊ฒฐ๊ณผ๋ ์ ๋์ค์ง๋ง ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ํ์ ํ ๋ฎ๋ค.
์ด๋ ๊ฒ ํด๋์ค๋ค ๊ฐ์ ์์ฌ์ํต, ์ํธ ์์ฉ ํ๋ ๊ฒฝ์ฐ์ ํด๋์ค ์์ ์ ๋ ธ์ถํ๋ ๊ฒ์ด ์๋๋ผ ๊ณ์ฝ์์ ์ ํ ๊ณ์ฝ์ ์๊ฑฐํด์ ์์ฌ์ํต ํ๋๋กํ๋ฉด ์ด๋จ๊น?
์ฌ๊ธฐ์ ๊ณ์ฝ์๊ฐ ๋ฐ๋ก ์ธํฐํ์ด์ค๊ฐ ๋๋ค. ์ด๊ฒ์ด ํด๋์ค ๋์ปคํ๋ง์ ๋จ์ด์ด๋ค.
์ธํฐํ์ด์ค๋ฅผ ํตํด์ ํด๋์ค ๊ฐ์ ์์ฌ์ํต, ์ํธ์์ฉ ํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์์ ํด๋ณธ๋ค.
1. ์ฐ์ ํผ์ ๋ง๋๋ ์ธํฐํ์ด์ค์ ์๊ธ์ ์ง์ด์ ๋ฟ๋ฆฌ๋ ์ธํฐํ์ด์ค๋ฅผ ์๋ก ๋ง๋ค์ด์ค๋ค.
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
interface SaltTopping {
addSalt(cup: CoffeeCup): CoffeeCup;
}
2. ๋ฐํฌ ์คํ ํด๋์ค์ ์ํธ ๋ฏน์ ํด๋์ค์ ๊ฐ๊ฐ ์์์ ๋ง๋ค์ด์ค ์ธํฐํ์ด์ค๋ฅผ ์ implements ํด์ค๋ค.
์ด๋ ๊ฒ ๊ฐ๊ฐ ์ ํด์ง ๊ท์ฝ์(์ธํฐํ์ด์ค)๋ฅผ implementsํ๊ณ ๊ท๊ฒฉ ์ฌํญ์ ๋ง๋ ํจ์๋ฅผ ๊ตฌํํ ํด๋์ค๊ฐ ๋์๋ค.(์๋ ์๋ ํจ์๋ค์์ผ๋ก)
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer implements SaltTopping {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
3. ์ฌ์ฉํ๋ ๊ฒ์์ ์ง์ ์ ์ผ๋ก ๋ฐํฌ ์คํ ํด๋์ค์ ์ํธ ๋ฏน์ ํด๋์ค๋ฅผ ๋ฐ์์ค๋ ๊ฒ์ด ์๋๋ผ,
๊ทธ ์๋ฆฌ๋ฅผ ์ธํฐํ์ด์ค๋ก ๋์ฒดํด์ค๋ค.
// CoffeMachine ํด๋์ค๋ฅผ ์์๋ฐ์ CafeLatteMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class CafeLatteMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์ ์๋น, ๋ฌผ ์๋น, ๋ฌผ ๊ฐ์ด ๋ค ๋๋๊ณ ์์ฑ๋ ์ปคํผ๊ฐ ๋ฐํ
return this.milkFrother.addMilkform(coffee);
}
}
// CoffeMachine ํด๋์ค ๋ฅผ ์์๋ฐ์ saltCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
return this.saltTopping.addSalt(coffee);
}
}
// ๋ง๋ค๊ณ ์ถ์๋ saltCafeLatteCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCafeLatteCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
const saltAdded = this.saltTopping.addSalt(coffee);
return this.milkFrother.addMilkform(saltAdded);
}
}
์์๊ฐ์ ํด๋์ค ๊ฐ ๊ฐํ ์ปคํ๋ง์ด ํ๋ ธ๋ค!
์ด์ ํด๋์ค๋ค์ ๋ฉด๋๋ฉด์ด ์๋๋ผ ์ธํฐํ์ด์ค๋ฅผ ํตํด์๋ง ๊ณ์ฝ์ ๋ง์ถ์ด ์์ฌ์ํ์ ํ๊ฒ ๋์๋ค.
<์ ์ฒด์ฝ๋>
// //์ปคํผ๋จธ์ ๋ง๋ค๊ธฐ
type CoffeeCup = {
orderShot: number;
hasMilk?: boolean;
hasSalt?: boolean;
};
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
interface SaltTopping {
addSalt(cup: CoffeeCup): CoffeeCup;
}
interface CoffeeMaker {
makeCoffee(shots: number): CoffeeCup;
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer implements SaltTopping {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
protected static ONE_SHOT_CAPSULE: number = 3;
protected static ONE_CUP_WATER: number = 10;
static makeMachine(beans: number, water: number): CoffeMachine {
return new CoffeMachine(beans, water);
}
public constructor(
protected capsule: number = 3,
protected water: number = 10
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
return this.extract(orderShot);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
// CoffeMachine ํด๋์ค๋ฅผ ์์๋ฐ์ CafeLatteMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class CafeLatteMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์ ์๋น, ๋ฌผ ์๋น, ๋ฌผ ๊ฐ์ด ๋ค ๋๋๊ณ ์์ฑ๋ ์ปคํผ๊ฐ ๋ฐํ
return this.milkFrother.addMilkform(coffee);
}
}
// CoffeMachine ํด๋์ค ๋ฅผ ์์๋ฐ์ saltCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
return this.saltTopping.addSalt(coffee);
}
}
// ๋ง๋ค๊ณ ์ถ์๋ saltCafeLatteCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCafeLatteCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
const saltAdded = this.saltTopping.addSalt(coffee);
return this.milkFrother.addMilkform(saltAdded);
}
}
const cheapMilkSteamer = new CheapMilkSteamer();
const saltMixer = new SaltMixer();
const saltCoffeeMaker = new saltCoffeeMachine(100, 100, saltMixer);
const saltCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const latteMaker = new CafeLatteMachine(100, 100, cheapMilkSteamer);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
saltCoffeeMaker,
saltCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
+ ์ถ๊ฐ ์คํ
-1 implements MilkFrother ์ํ์ธ ๋ค์ํ ์ฐ์ ๊ฑฐํ๊ธฐ๋ค์ ์์ฑํด๋ณธ๋ค.
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์น์ฆํผ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class CheeseMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamCheeseMilk(): void {
console.log("๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamCheeseMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์ ๊ธฐ๋ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class OrganicMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamOrganicMilk(): void {
console.log("๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamOrganicMilk();
return {
...cup,
hasMilk: true,
};
}
}
-2 ์ ๊ธฐ๋์ฐ์ ์คํ ํด๋์ค์ ์น์ฆ์ฐ์ ์คํ ํด๋์ค ์์ฑํด์ฃผ๊ณ
์ ๊ธฐ๋ ์ฐ์ ์ ์น์ฆ ์ฐ์ ๋ฅผ ์ฌ๋ฏธ๋๊ฒ ์๊ณ ์ ํ๋ ํด๋์ค๋ค์ ์์๊ฐ์ ์์ฑํด์ค๋ค.(๊ฐ๊ฒฉ์ค๋ฌ์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ ์๊ฐ)
๊ธฐ์กด์ ์๋ ์ปคํผ๋จธ์ ํด๋์ค ์์ฑ ์ฝ๋๋ฅผ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ ํ๋ค์์ ์ด๋ฆ๋ง ์กฐ๊ธ ๋ฐ๊ฟ์ฃผ๊ณ (์ฝ๋ ์ฌ์ฌ์ฉ)
๊ฐ๋ฐ์ ์ํ๋ ๋ถํ(ํด๋์ค)์ ์ฉ๋์ ๋ง๊ฒ ๊ฐ์ ธ๋ค ๋ฃ์ด์ฃผ๊ธฐ๋ง ํ๋ฉด๋๋ค.
์ํ๋ ๊ธฐ๋ฅ๋ค์ ์กฐ๋ฆฝํ๋ค๋ ์ ์์ ์ปดํฌ์ง์ ์ด์, ๊ฐ๋ ฅํ ์ธํฐํ์ด์ค์ธ ๊ฒ์ด๋ค.
const cheapMilkSteamer = new CheapMilkSteamer();
const saltMixer = new SaltMixer();
const organicMilkSteamer = new OrganicMilkSteamer();
const cheeseMilkSteamer = new CheeseMilkSteamer();
//const saltCoffeeMaker = new saltCoffeeMachine(100, 100, saltMixer);
const saltCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const saltCheeseCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheeseMilkSteamer
);
const saltOrganicCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
organicMilkSteamer
);
const latteMaker = new CafeLatteMachine(100, 100, cheapMilkSteamer);
const cheeselatteMaker = new CafeLatteMachine(100, 100, cheeseMilkSteamer);
const organicLatteMaker = new CafeLatteMachine(100, 100, organicMilkSteamer);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
//saltCoffeeMaker,
saltCafeLatteMaker,
cheeselatteMaker,
organicLatteMaker,
saltCheeseCafeLatteMaker,
saltOrganicCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
<์ถ๋ ฅ ๊ฒฐ๊ณผ> ๋ง์กฑ์ค๋ฌ์ด ํผํฌ๋จผ์ค๋ฅผ ๋ณด์ฌ์ค๋ค.
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
{ orderShot: 1, hasMilk: false, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
PS C:\Users\User\gitprogect\TsOOP> ts-node 2-tsOOP/1.ts
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
<ํ์ฌ๊น์ง ์ ์ฒด ์ฝ๋>
// //์ปคํผ๋จธ์ ๋ง๋ค๊ธฐ
type CoffeeCup = {
orderShot: number;
hasMilk?: boolean;
hasSalt?: boolean;
};
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
interface SaltTopping {
addSalt(cup: CoffeeCup): CoffeeCup;
}
interface CoffeeMaker {
makeCoffee(shots: number): CoffeeCup;
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์น์ฆํผ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class CheeseMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamCheeseMilk(): void {
console.log("๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamCheeseMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์ ๊ธฐ๋ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class OrganicMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamOrganicMilk(): void {
console.log("๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamOrganicMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer implements SaltTopping {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
protected static ONE_SHOT_CAPSULE: number = 3;
protected static ONE_CUP_WATER: number = 10;
static makeMachine(beans: number, water: number): CoffeMachine {
return new CoffeMachine(beans, water);
}
public constructor(
protected capsule: number = 3,
protected water: number = 10
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
return this.extract(orderShot);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
// CoffeMachine ํด๋์ค๋ฅผ ์์๋ฐ์ CafeLatteMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class CafeLatteMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์ ์๋น, ๋ฌผ ์๋น, ๋ฌผ ๊ฐ์ด ๋ค ๋๋๊ณ ์์ฑ๋ ์ปคํผ๊ฐ ๋ฐํ
return this.milkFrother.addMilkform(coffee);
}
}
// CoffeMachine ํด๋์ค ๋ฅผ ์์๋ฐ์ saltCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
return this.saltTopping.addSalt(coffee);
}
}
// ๋ง๋ค๊ณ ์ถ์๋ saltCafeLatteCoffeeMachine ํด๋์ค์ด๋ค.\\\\\\\\\\\\\\\\\\\\\\\\\\\
class saltCafeLatteCoffeeMachine extends CoffeMachine {
public constructor(
protected capsule: number = 3,
protected water: number = 10,
private saltTopping: SaltTopping,
private milkFrother: MilkFrother
) {
super(capsule, water);
}
makeCoffee(orderShot: number): CoffeeCup {
const coffee = super.makeCoffee(orderShot);
const saltAdded = this.saltTopping.addSalt(coffee);
return this.milkFrother.addMilkform(saltAdded);
}
}
const cheapMilkSteamer = new CheapMilkSteamer();
const saltMixer = new SaltMixer();
const organicMilkSteamer = new OrganicMilkSteamer();
const cheeseMilkSteamer = new CheeseMilkSteamer();
//const saltCoffeeMaker = new saltCoffeeMachine(100, 100, saltMixer);
const saltCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const saltCheeseCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
cheeseMilkSteamer
);
const saltOrganicCafeLatteMaker = new saltCafeLatteCoffeeMachine(
100,
100,
saltMixer,
organicMilkSteamer
);
const latteMaker = new CafeLatteMachine(100, 100, cheapMilkSteamer);
const cheeselatteMaker = new CafeLatteMachine(100, 100, cheeseMilkSteamer);
const organicLatteMaker = new CafeLatteMachine(100, 100, organicMilkSteamer);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
//saltCoffeeMaker,
saltCafeLatteMaker,
cheeselatteMaker,
organicLatteMaker,
saltCheeseCafeLatteMaker,
saltOrganicCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
์์ง ๊ฐ์ ํด์ผํ ์ ๋ค์ด ๋ณด์ธ๋ค.
์ด๋ฆ์ด ๋ณต์กํ ์ฌ๋ฌ ์ข ๋ฅ์ ํด๋์ค๋ค์ด ๋ค ํ์์์ด์ก์ผ๋ฏ๋ก ํ์ํ ์ต์ํ์ ํด๋์ค๋ง ๋จ๊ฒจ๋๊ณ ๋ค ์ง์๋ฒ๋ฆฐ๋ค.
๊ฐ๊ฐ์ ๊ธฐ๋ฅ์ ์ํํ๋ ๋ถํ๋ค(ํด๋์ค)์ ๋ถํ ๋ช ์ธ์์ธ ์ธํฐํ์ด์ค, ์ปคํผ๋จธ์ ํด๋์ค๋ง ๋จ๊ฒจ๋๋ค.
๋์ , ์ปคํผ๋จธ์ ํด๋์ค์ salt์ milkform ์์ฑ์ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ makeCoffee() ๋ก์ง์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํด์ค๋ค.
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
const coffeeCup = this.extract(orderShot);
const saltAdded = this.salt.addSalt(coffeeCup);
return this.milkform.addMilkform(saltAdded);
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
private static ONE_SHOT_CAPSULE: number = 3;
private static ONE_CUP_WATER: number = 10;
public constructor(
private capsule: number = 3,
private water: number = 10,
private salt: SaltTopping,
private milkform: MilkFrother
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
const coffeeCup = this.extract(orderShot);
const saltAdded = this.salt.addSalt(coffeeCup);
return this.milkform.addMilkform(saltAdded);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
<ํ์ฌ ์ ์ฒด ์ฝ๋>
// //์ปคํผ๋จธ์ ๋ง๋ค๊ธฐ
type CoffeeCup = {
orderShot: number;
hasMilk?: boolean;
hasSalt?: boolean;
};
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
interface SaltTopping {
addSalt(cup: CoffeeCup): CoffeeCup;
}
interface CoffeeMaker {
makeCoffee(shots: number): CoffeeCup;
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์น์ฆํผ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class CheeseMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamCheeseMilk(): void {
console.log("๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamCheeseMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์ ๊ธฐ๋ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class OrganicMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamOrganicMilk(): void {
console.log("๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamOrganicMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer implements SaltTopping {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
private static ONE_SHOT_CAPSULE: number = 3;
private static ONE_CUP_WATER: number = 10;
public constructor(
private capsule: number = 3,
private water: number = 10,
private salt: SaltTopping,
private milkform: MilkFrother
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
const coffeeCup = this.extract(orderShot);
const saltAdded = this.salt.addSalt(coffeeCup);
return this.milkform.addMilkform(saltAdded);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
implements MilkFrother์ธ NoMilk์
//์ฐ์ ํผ ์์
class NoMilkSteamer implements MilkFrother {
//(1)๋ฐ์์จ ์ปต์๋ค ์ถ๊ฐ ์์
ํ์ง์๊ณ , ๊ทธ๋๋ก ๋ค์ ๋ฐํ
addMilkform(cup: CoffeeCup): CoffeeCup {
return cup
}
}
//์๊ธ ํ ํ ์์
class NoSaltMixer implements SaltTopping {
//(1)๋ฐ์์จ ์ปต์๋ค ์ถ๊ฐ ์์
ํ์ง์๊ณ , ๊ทธ๋๋ก ๋ค์ ๋ฐํ
addSalt(cup: CoffeeCup): CoffeeCup {
return cup;
}
}
๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ ์ฉ๋์ ๋ง๋ ํด๋์ค๋ค์ ์์ฑํด์ค๋ค.
//์๊ธ๊ด๋ จ
const nosaltMixer = new NoSaltMixer();
const saltMixer = new SaltMixer();
//์ฐ์ ๊ด๋ จ
const noMilkSteamer = new NoMilkSteamer();
const cheapMilkSteamer = new CheapMilkSteamer();
const organicMilkSteamer = new OrganicMilkSteamer();
const cheeseMilkSteamer = new CheeseMilkSteamer();
๊ทธ ๋ค์ ์์ ์ ์ฉ๋์ ๋ง๊ฒ ๋ถํํด๋์ค๋ค์ ์ ๋ผ์๋ฃ์ด์
์๋ก์ด ํด๋์ค๋ค์ ๋นต ๋นต ๋นต ์ฐ์ด๋ด๋ ์ผ๋ง ๋จ์๋ค.
//์๊ธ๊ด๋ จ
const nosaltMixer = new NoSaltMixer();
const saltMixer = new SaltMixer();
//์ฐ์ ๊ด๋ จ
const noMilkSteamer = new NoMilkSteamer();
const cheapMilkSteamer = new CheapMilkSteamer();
const organicMilkSteamer = new OrganicMilkSteamer();
const cheeseMilkSteamer = new CheeseMilkSteamer();
const saltCoffeeMaker = new CoffeMachine(100, 100, saltMixer, noMilkSteamer);
const saltCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const saltCheeseCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
cheeseMilkSteamer
);
const saltOrganicCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
organicMilkSteamer
);
const latteMaker = new CoffeMachine(100, 100, nosaltMixer, cheapMilkSteamer);
const cheeselatteMaker = new CoffeMachine(
100,
100,
nosaltMixer,
cheeseMilkSteamer
);
const organicLatteMaker = new CoffeMachine(
100,
100,
nosaltMixer,
organicMilkSteamer
);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
saltCoffeeMaker,
saltCafeLatteMaker,
cheeselatteMaker,
organicLatteMaker,
saltCheeseCafeLatteMaker,
saltOrganicCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
<์ต์ข ์ฝ๋>
// //์ปคํผ๋จธ์ ๋ง๋ค๊ธฐ
type CoffeeCup = {
orderShot: number;
hasMilk?: boolean;
hasSalt?: boolean;
};
interface MilkFrother {
addMilkform(cup: CoffeeCup): CoffeeCup;
}
interface SaltTopping {
addSalt(cup: CoffeeCup): CoffeeCup;
}
interface CoffeeMaker {
makeCoffee(shots: number): CoffeeCup;
}
//์ฐ์ ํผ ์์
class NoMilkSteamer implements MilkFrother {
//(1)๋ฐ์์จ ์ปต์๋ค ์ถ๊ฐ ์์
ํ์ง์๊ณ , ๊ทธ๋๋ก ๋ค์ ๋ฐํ
addMilkform(cup: CoffeeCup): CoffeeCup {
return cup;
}
}
//์ผ๋ฐ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////////////////////////
class CheapMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamMilk(): void {
console.log("๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์น์ฆํผ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class CheeseMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamCheeseMilk(): void {
console.log("๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamCheeseMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์ ๊ธฐ๋ ์ฐ์ ๊ฑฐํ๊ธฐ//////////////////////////////////////////////////
class OrganicMilkSteamer implements MilkFrother {
//(1)์ฐ์ ๊ฑฐํ์ ๋ง๋๋ ๋ด๋ถ ํจ์
private steamOrganicMilk(): void {
console.log("๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ");
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ๋ง๋ค์ด์ง ์ฐ์ ๊ฑฐํ(1)์ ๋ถ์ด์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addMilkform(cup: CoffeeCup): CoffeeCup {
this.steamOrganicMilk();
return {
...cup,
hasMilk: true,
};
}
}
//์๊ธ ํ ํ ์์
class NoSaltMixer implements SaltTopping {
//(1)๋ฐ์์จ ์ปต์๋ค ์ถ๊ฐ ์์
ํ์ง์๊ณ , ๊ทธ๋๋ก ๋ค์ ๋ฐํ
addSalt(cup: CoffeeCup): CoffeeCup {
return cup;
}
}
//์๊ธ๋ฏน์///////////////////////////////////////////////////////////////////////////////
class SaltMixer implements SaltTopping {
//(1)์๊ธ์ ์ง๋ ๋ด๋ถ ํจ์
private getSalt() {
console.log("์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค");
return true;
}
//(2)๋ง๋ค์ด์ง ์ปคํผ์ปต์ ๋ฐ์์, ์ง์ ์๊ธ(1)์ ๋ฟ๋ ค์ ์ด ์ปคํผ์ปต์ ๋ค์ ๋ฆฌํดํ๋ ํจ์
addSalt(cup: CoffeeCup): CoffeeCup {
const salt = this.getSalt();
return {
...cup,
hasSalt: salt,
};
}
}
// CoffeeMaker ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ CoffeMachine ํด๋์ค์ด๋ค.////////////////////////////
class CoffeMachine implements CoffeeMaker {
private static ONE_SHOT_CAPSULE: number = 3;
private static ONE_CUP_WATER: number = 10;
public constructor(
private capsule: number = 3,
private water: number = 10,
private salt: SaltTopping,
private milkform: MilkFrother
) {}
makeCoffee(orderShot: number): CoffeeCup {
this.checkMaterials(orderShot);
console.log("์บก์์ฐ๊ธฐ ์ " + this.capsule);
this.useCapsule(orderShot);
console.log("๋ฌผ์ฐ๊ธฐ ์ " + this.water);
this.useWater();
this.heatWater();
const coffeeCup = this.extract(orderShot);
const saltAdded = this.salt.addSalt(coffeeCup);
return this.milkform.addMilkform(saltAdded);
}
protected checkMaterials(orderShot: number) {
if (this.capsule < orderShot * CoffeMachine.ONE_SHOT_CAPSULE) {
throw new Error(`์ปคํผ์บก์ ๋ถ์กฑ!!! ํ์ฌ ๋ณด์ ์บก์ : ${this.capsule}`);
}
if (this.water < CoffeMachine.ONE_CUP_WATER) {
throw new Error(`๋ฌผ ๋ถ์กฑ!!! ๋จ์ ๋ฌผ ${this.water}`);
}
}
clean(): void {
console.log("์ปคํผ๋จธ์ ํ๊ตฌ๋ ์ค!");
}
private extract(shots: number): CoffeeCup {
return {
orderShot: shots,
hasMilk: false,
};
}
private heatWater() {
console.log("๋ฌผ ๋์ด๋ ์ค...");
}
private useCapsule(shot: number) {
console.log("์บก์์ฐ๋ฌ์์ต๋๋ค.");
this.capsule -= shot * CoffeMachine.ONE_SHOT_CAPSULE;
console.log("์บก์ ์ฐ๊ณ ๋ ํ" + this.capsule);
}
protected useWater() {
console.log("๋ฌผ์ฐ๋ฌ์์ต๋๋ค.");
this.water -= CoffeMachine.ONE_CUP_WATER;
console.log("๋ฌผ์ฐ๊ณ ๋ ํ " + this.water);
}
addCapsule(capsule: number) {
this.capsule += capsule;
}
fulfillWater(water: number) {
this.water += water;
}
get Water(): number {
return this.water;
}
get Capsule(): number {
return this.capsule;
}
}
//์๊ธ๊ด๋ จ
const nosaltMixer = new NoSaltMixer();
const saltMixer = new SaltMixer();
//์ฐ์ ๊ด๋ จ
const noMilkSteamer = new NoMilkSteamer();
const cheapMilkSteamer = new CheapMilkSteamer();
const organicMilkSteamer = new OrganicMilkSteamer();
const cheeseMilkSteamer = new CheeseMilkSteamer();
const saltCoffeeMaker = new CoffeMachine(100, 100, saltMixer, noMilkSteamer);
const saltCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
cheapMilkSteamer
);
const saltCheeseCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
cheeseMilkSteamer
);
const saltOrganicCafeLatteMaker = new CoffeMachine(
100,
100,
saltMixer,
organicMilkSteamer
);
const latteMaker = new CoffeMachine(100, 100, nosaltMixer, cheapMilkSteamer);
const cheeselatteMaker = new CoffeMachine(
100,
100,
nosaltMixer,
cheeseMilkSteamer
);
const organicLatteMaker = new CoffeMachine(
100,
100,
nosaltMixer,
organicMilkSteamer
);
const coffeMakers: CoffeeMaker[] = [
latteMaker,
saltCoffeeMaker,
saltCafeLatteMaker,
cheeselatteMaker,
organicLatteMaker,
saltCheeseCafeLatteMaker,
saltOrganicCafeLatteMaker,
];
coffeMakers.forEach((maker: CoffeeMaker) => {
console.log("------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------");
console.log(maker.makeCoffee(1));
});
<์ต์ข ์ถ๋ ฅ ๊ฒฐ๊ณผ>
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
{ orderShot: 1, hasMilk: false, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ชฝ๊ธ๋ชฝ๊ธ ํฌ์ญํฌ์ญํ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๋ถ๋๋ฌ์ด ์น์ฆ๊ฐ ๋
น์๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }
------------์ปคํผ๋จธ์ ๊ฐ๋~!-- ----------
์บก์์ฐ๊ธฐ ์ 100
์บก์์ฐ๋ฌ์์ต๋๋ค.
์บก์ ์ฐ๊ณ ๋ ํ97
๋ฌผ์ฐ๊ธฐ ์ 100
๋ฌผ์ฐ๋ฌ์์ต๋๋ค.
๋ฌผ์ฐ๊ณ ๋ ํ 90
๋ฌผ ๋์ด๋ ์ค...
์๊ธ์ ํ๊ผฌ์ง ์ง์๋ค
๊ณ ๊ธ ์ ๊ธฐ๋ ์ฐ์ ๋ก ๋ง๋ ์ฐ์ ํผ
{ orderShot: 1, hasMilk: true, hasSalt: true }