TypeScript/ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ TypeScript

[ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ] ๋‹คํ˜•์„ฑ(polymorphism)์ด ๋ญ๊ฐ€ ์ข‹์€ ๊ฒƒ์ผ๊นŒ?

Rainbow๐ŸŒˆCoder 2022. 4. 22. 15:06
728x90

ํฌ์ŠคํŒ… ์ œ๋ชฉ์˜ ํ•ด๋‹ต์€ ์•„๋ž˜ ์ฝ”๋“œ์— ์žˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ ๋„, ์ง์ž‘ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด ํฌ์ŠคํŒ… ๊ฐ€์žฅ ์•„๋ž˜์— ๊ธฐ์žฌํ•ด๋‘์—ˆ๋‹ค!

//ํžŒํŠธ1

const machines = [
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
];

machines.forEach((machine) => {
  console.log("------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------");
  console.log(machine.makeCoffee(1));
});

 

ํžŒํŠธ2

์•„๋ž˜์™€ ๊ฐ™์ด ์ปคํ”ผ๋จธ์‹  ํด๋ž˜์Šค์™€ ์นดํŽ˜๋ผ๋–ผ๋จธ์‹  ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

//   //์ปคํ”ผ๋จธ์‹  ๋งŒ๋“ค๊ธฐ
type CoffeeCup = {
  orderShot: number;
  hasMilk: boolean;
};

interface CoffeeMaker {
  makeCoffee(shots: number): CoffeeCup;
}

//์œ„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
class CoffeMachine implements CoffeeMaker {
  private 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;
  }
}

// tslint:disable-next-line: max-classes-per-file
class CafeLatteMachine extends CoffeMachine {
  protected static ONE_CUP_WATER: number = 8;
  private static ONE_CUP_Milk: number = 2;

  public constructor(
    protected capsule: number = 3,
    protected water: number = 10,
    private milk: number,
    public readonly serialNumber: string
  ) {
    super(capsule, water);
  }

  makeCoffee(orderShot: number): CoffeeCup {
    const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์А ์†Œ๋น„, ๋ฌผ ์†Œ๋น„, ๋ฌผ ๊ฐ€์—ด ๋‹ค ๋๋‚˜๊ณ  ์™„์„ฑ๋œ ์ปคํ”ผ๊ฐ€ ๋ฐ˜ํ™˜
    //๋ถ€๋ชจ์—์„œ ๋ฐ›์•„์˜จ ์ปคํ”ผ ์™„์„ฑํ’ˆ์— ์šฐ์œ ๋งŒ ๋ถ€์–ด์ฃผ์ž!!!
    this.steamMilk();
    this.pourMilk();
    return { orderShot: orderShot, hasMilk: true };
  }

  //์˜ค๋ฒ„๋ผ์ด๋”ฉ
  checkMaterials(orderShot: number) {
    super.checkMaterials(orderShot);
    if (this.milk < CafeLatteMachine.ONE_CUP_Milk) {
      throw new Error(`์šฐ์œ  ๋ถ€์กฑ!!! ํ˜„์žฌ ๋ณด์œ  ์šฐ์œ ๋Ÿ‰ : ${this.milk}`);
    }
  }
  useWater() {
    console.log("๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.");
    this.water -= CafeLatteMachine.ONE_CUP_WATER;
    console.log("๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ " + this.water);
  }

  private steamMilk(): void {
    console.log("์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...");
  }

  private pourMilk() {
    console.log("์šฐ์œ  ๋ถ“๋Š” ์ค‘...");
    this.milk -= CafeLatteMachine.ONE_CUP_Milk;
    console.log("์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค " + this.milk);
  }

  public fulfillMilk(milk: number) {
    this.milk += milk;
  }

  get Milk(): number {
    return this.milk;
  }
}

 

ํด๋ž˜์Šค ๊ตฌ๋™ ์—ฌ๋ถ€๋Š” ์•„๋ž˜ ์ฝ˜์†”๋“ค๋กœ ์ฐ์–ด๋ณด๋ฉด ์ž˜ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

const machine = new CoffeMachine(100, 100);
const latteMachine = new CafeLatteMachine(100, 100, 2, "1S");

const latte1 = latteMachine.makeCoffee(10);
console.log("์ฒซ๋ฒˆ์งธ ๋ผ๋–ผ...๋‘๊ตฌ๋‘๊ตฌ๋‘๊ตฌ...");
console.log(latte1);

console.log("์ง€๊ธˆ ์šฐ์œ  ์ƒํƒœ๋Š”? : " + latteMachine.Milk);
console.log("์šฐ์œ ๊ฐ€ ์—†์œผ๋‹ˆ๊นŒ ์ถฉ์ „ํ•ด์ฃผ์ž");
latteMachine.fulfillMilk(2);

const latte2 = latteMachine.makeCoffee(10);
console.log("๋‘๋ฒˆ์งธ ๋ผ๋–ผ~~~");
console.log(latte2);

const latte3 = latteMachine.makeCoffee(10);
console.log("์šฐ์œ ๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ ์„ธ๋ฒˆ์งธ ๋ผ๋–ผ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋ฉด~~?");
console.log(latte3);
console.log(latteMachine.serialNumber);

 

 

์—ฌ๊ธฐ์— ์†Œ๊ธˆ์ด ๋“ค์–ด๊ฐ€๋Š” ์†Œ๊ธˆ ์ปคํ”ผ๋จธ์‹ ๋„ ๋งŒ๋“ค์–ด๋ณธ๋‹ค.

 

์ด์ฒ˜๋Ÿผ ๋‹คํ˜•์„ฑ์„ ์ด์šฉํ•˜๋ฉด ํ•œ๊ฐ€์ง€์˜ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜, ํ•œ๊ฐ€์ง€์˜ ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด์„œ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋ฅผ ๋˜ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋‹คํ˜•์„ฑ์˜ ์žฅ์ ์„ ๋‘๋ˆˆ์œผ๋กœ ๋˜‘๋˜‘ํžˆ ํ™•์ผํ•ด ๋ณผ ํƒ€์ด๋ฐ์ด ๋‹ค๊ฐ€์™”๋‹ค.

 

์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ปคํ”ผ๋จธ์‹ ๋“ค(ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ธ์Šคํ„ด์Šค, ๊ณง ํ•ด๋‹น ์ฝ”๋“œ์—์„œ๋Š” ์ปคํ”ผ๋จธ์‹  :_)์ด ๋“ค์–ด์žˆ๋Š” ๋ฐฐ์—ด์ด ์žˆ๋‹ค๊ณ  ์น˜์ž.

const machines = [
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
];

๋‹คํ˜•์„ฑ ์ตœ๊ณ ์˜ ์žฅ์ !

๋ฐ”๋กœ ์ด machines๋ฅผ ๋น™๊ธ€๋น™๊ธ€ ๋Œ๋ฉด์„œ ๊ฐ๊ฐ์˜ ๋จธ์‹ ๋“ค์„ ํ”„๋กœํผํ‹ฐ(ํ˜น์€ ํ•จ์ˆ˜)๋ฅผ ๋ฐ›์•„์™€์„œ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค!

const machines = [
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
];

machines.forEach((machine) => {
  console.log("------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------");
  console.log(machine.makeCoffee(1));
});

<์ถœ๋ ฅ๊ฒฐ๊ณผ> ์ด๋ ‡๊ฒŒ ๋ฐฐ์—ด์— ์žˆ๋Š” ๋ชจ๋“  ์ปคํ”ผ๋จธ์‹ ๋“ค์— ์ ‘๊ทผํ•˜๋ฉด์„œ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์ž˜ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 25
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„22
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 15
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 15
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„12
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 17
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 23
{ orderShot: 1, hasMilk: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 5
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„2
๋ฌผ์“ฐ๊ธฐ ์ „ 10
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 0
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false, hasSalt: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 25
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„22
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 15
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 15
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„12
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 17
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 23
{ orderShot: 1, hasMilk: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 5
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„2
๋ฌผ์“ฐ๊ธฐ ์ „ 10
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 0
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false, hasSalt: true }

 

์ด์ฒ˜๋Ÿผ ๋‹คํ˜•์„ฑ์˜ ์žฅ์ ์€ ๋‹ค์–‘ํ•œ ํด๋ž˜์Šค๋“ค์ด ํ•œ๊ฐ€์ง€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ๋™์ผํ•œ ๋ถ€๋ชจํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ์ƒํƒœ๋ผ๋ฉด,

๊ณตํ†ต API๋ฅผ ์œ„์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

 

 

์œ„ ์บก์ฒ˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ด์œ 

TSC๊ฐ€ machines๋ฅผ CoffeeMachine[] ๋กœ ์ด๋ฏธ ์ถ”๋ก ์ด ๋๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!

์—ฌ๊ธฐ์„œ ๋” ๊ธฐ๊ฐ€ ๋ง‰ํžŒ ๊ฒƒ์€,

 

์นดํŽ˜๋ผ๋–ผ๋จธ์‹ ๊ณผ ์†Œ๊ธˆ์ปคํ”ผ๋จธ์‹ ์€ ์ปคํ”ผ๋จธ์‹ ์ด๋‹ค. (ํด๋ž˜์Šค ์ƒ์†๋ฐ›์•˜์œผ๋‹ˆ๊นŒ) ์ปคํ”ผ๋จธ์‹ ์€ ์ปคํ”ผ๋ฉ”์ด์ปค(์ธํ„ฐํŽ˜์ด์Šค)์ด๋‹ค. (์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ํ–ˆ์œผ๋‹ˆ๊นŒ) ๊ทธ๋ ‡๋‹ค๋ฉด ์นดํŽ˜๋ผ๋–ผ๋จธ์‹ ๊ณผ ์†Œ๊ธˆ์ปคํ”ผ๋จธ์‹  ์—ญ์‹œ ์ปคํ”ผ๋ฉ”์ด์ปค์ด๋‹ค. ์ด ์ด๋ก ์ ์ธ ์‚ฌ์‹ค์„ ํ†ตํ•ด ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ์ค€์œผ๋กœ ๊ณตํ†ตAPI ์ œํ•œ์„ ๊ฑธ์–ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๋œป์ด๋‹ค.

 

๋ฐฐ์—ด์˜ ํƒ€์ž…์„ ์ธํ„ฐํŽ˜์ด์Šค ๋ฐฐ์—ด๋กœ ์ œํ•œ์„ ๊ฑธ์–ด์ฃผ๋ฉด!

const machines: CoffeeMaker[] = [
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
];

์•„๋ž˜ ์บก์ณ์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ณตํ†ตAPI๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ๊ทœ์•ฝ๋˜์–ด์žˆ๋Š” ํ•จ์ˆ˜ ๋ฟ์ด๋‹ค.

 

์ด์ฒ˜๋Ÿผ ๋‹คํ˜•์„ฑ์ด๋ž€, ํ•˜๋‚˜์˜ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ๋˜๋Š” ๊ฐ™์€ ๋ถ€๋ชจ์˜ ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•œ ์ž์‹ํด๋ž˜์Šค๋“ค์ด,

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

  

์ด๋ ‡๊ฒŒ ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค ํ˜น์€ ๊ฐ™์€ ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณผ์ •์—์„œ,

๊ฐœ๋ฐœ์ž๋Š” ๊ฐ ํด๋ž˜์Šค๋“ค์˜ ์„ธ๋ถ€์ ์ธ ๋‚ด๋ถ€ ๊ตฌํ˜„์‚ฌํ•ญ์„ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ  ๊ณตํ†ต API๋งŒ์„ ๋ณด๊ณ  ๋ฝ‘์•„ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋‹ˆ ์‚ฌ์šฉ์‹œ์—๋„ ๊ฐ„ํŽธํ•จ์„ ๋А๋‚„ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

<๋ณธ ํฌ์ŠคํŒ…์— ํ™œ์šฉํ•œ ์ตœ์ข… ์†Œ์Šค ์ฝ”๋“œ>

//   //์ปคํ”ผ๋จธ์‹  ๋งŒ๋“ค๊ธฐ
type CoffeeCup = {
  orderShot: number;
  hasMilk?: boolean;
  hasSalt?: boolean;
};

interface CoffeeMaker {
  makeCoffee(shots: number): CoffeeCup;
}

// CoffeeMaker ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” CoffeMachine ํด๋ž˜์Šค์ด๋‹ค.
class CoffeMachine implements CoffeeMaker {
  private 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 {
  protected static ONE_CUP_WATER: number = 8;
  private static ONE_CUP_Milk: number = 2;

  public constructor(
    protected capsule: number = 3,
    protected water: number = 10,
    private milk: number,
    public readonly serialNumber: string
  ) {
    super(capsule, water);
  }

  makeCoffee(orderShot: number): CoffeeCup {
    const coffee = super.makeCoffee(orderShot); //๊ธฐ๋ณธ์ ์ธ ์บก์А ์†Œ๋น„, ๋ฌผ ์†Œ๋น„, ๋ฌผ ๊ฐ€์—ด ๋‹ค ๋๋‚˜๊ณ  ์™„์„ฑ๋œ ์ปคํ”ผ๊ฐ€ ๋ฐ˜ํ™˜
    //๋ถ€๋ชจ์—์„œ ๋ฐ›์•„์˜จ ์ปคํ”ผ ์™„์„ฑํ’ˆ์— ์šฐ์œ ๋งŒ ๋ถ€์–ด์ฃผ์ž!!!
    this.steamMilk();
    this.pourMilk();
    return { orderShot: orderShot, hasMilk: true };
  }

  //์˜ค๋ฒ„๋ผ์ด๋”ฉ
  checkMaterials(orderShot: number) {
    super.checkMaterials(orderShot);
    if (this.milk < CafeLatteMachine.ONE_CUP_Milk) {
      throw new Error(`์šฐ์œ  ๋ถ€์กฑ!!! ํ˜„์žฌ ๋ณด์œ  ์šฐ์œ ๋Ÿ‰ : ${this.milk}`);
    }
  }
  useWater() {
    console.log("๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.");
    this.water -= CafeLatteMachine.ONE_CUP_WATER;
    console.log("๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ " + this.water);
  }

  private steamMilk(): void {
    console.log("์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...");
  }

  private pourMilk() {
    console.log("์šฐ์œ  ๋ถ“๋Š” ์ค‘...");
    this.milk -= CafeLatteMachine.ONE_CUP_Milk;
    console.log("์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค " + this.milk);
  }

  public fulfillMilk(milk: number) {
    this.milk += milk;
  }

  get Milk(): number {
    return this.milk;
  }
}

// CoffeMachine ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ saltCoffeeMachine ํด๋ž˜์Šค์ด๋‹ค.
class saltCoffeeMachine extends CoffeMachine {
  //..
  makeCoffee(orderShot: number): CoffeeCup {
    const coffee = super.makeCoffee(orderShot);
    return {
      ...coffee,
      hasSalt: true,
    };
  }
}

const machines: CoffeeMaker[] = [
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
  new CoffeMachine(25, 25),
  new CafeLatteMachine(15, 25, 25, "S1"),
  new saltCoffeeMachine(5, 10),
];

machines.forEach((machine) => {
  console.log("------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------");
  console.log(machine.makeCoffee(1));
});

const machine = new CoffeMachine(100, 100);
const latteMachine = new CafeLatteMachine(100, 100, 2, "1S");

const latte1 = latteMachine.makeCoffee(10);
console.log("์ฒซ๋ฒˆ์งธ ๋ผ๋–ผ...๋‘๊ตฌ๋‘๊ตฌ๋‘๊ตฌ...");
console.log(latte1);

console.log("์ง€๊ธˆ ์šฐ์œ  ์ƒํƒœ๋Š”? : " + latteMachine.Milk);
console.log("์šฐ์œ ๊ฐ€ ์—†์œผ๋‹ˆ๊นŒ ์ถฉ์ „ํ•ด์ฃผ์ž");
latteMachine.fulfillMilk(2);

const latte2 = latteMachine.makeCoffee(10);
console.log("๋‘๋ฒˆ์งธ ๋ผ๋–ผ~~~");
console.log(latte2);

const latte3 = latteMachine.makeCoffee(10);
console.log("์šฐ์œ ๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ ์„ธ๋ฒˆ์งธ ๋ผ๋–ผ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋ฉด~~?");
console.log(latte3);
console.log(latteMachine.serialNumber);

<์ถœ๋ ฅ๊ฒฐ๊ณผ>

------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 25
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„22
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 15
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 15
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„12
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 17
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 23
{ orderShot: 1, hasMilk: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 5
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„2
๋ฌผ์“ฐ๊ธฐ ์ „ 10
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 0
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false, hasSalt: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 25
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„22
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 15
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 15
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„12
๋ฌผ์“ฐ๊ธฐ ์ „ 25
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 17
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 23
{ orderShot: 1, hasMilk: true }
------------์ปคํ”ผ๋จธ์‹  ๊ฐ€๋™~!------------
์บก์А์“ฐ๊ธฐ ์ „ 5
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„2
๋ฌผ์“ฐ๊ธฐ ์ „ 10
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 0
๋ฌผ ๋“์ด๋Š” ์ค‘...
{ orderShot: 1, hasMilk: false, hasSalt: true }
์บก์А์“ฐ๊ธฐ ์ „ 100
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„70
๋ฌผ์“ฐ๊ธฐ ์ „ 100
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 92
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 0
์ฒซ๋ฒˆ์งธ ๋ผ๋–ผ...๋‘๊ตฌ๋‘๊ตฌ๋‘๊ตฌ...
{ orderShot: 10, hasMilk: true }
์ง€๊ธˆ ์šฐ์œ  ์ƒํƒœ๋Š”? : 0
์šฐ์œ ๊ฐ€ ์—†์œผ๋‹ˆ๊นŒ ์ถฉ์ „ํ•ด์ฃผ์ž
์บก์А์“ฐ๊ธฐ ์ „ 70
์บก์А์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
์บก์А ์“ฐ๊ณ  ๋‚œ ํ›„40
๋ฌผ์“ฐ๊ธฐ ์ „ 92
๋ฌผ์“ฐ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.
๋ฌผ์“ฐ๊ณ  ๋‚œ ํ›„ 84
๋ฌผ ๋“์ด๋Š” ์ค‘...
์šฐ์œ  ๋ฐ์šฐ๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๋Š” ์ค‘...
์šฐ์œ  ๋ถ“๊ณ  ๋‚œ ๋’ค 0
๋‘๋ฒˆ์งธ ๋ผ๋–ผ~~~
{ orderShot: 10, hasMilk: true }
/Users/์œ ์ €๋ช…^_^/Desktop/ํ”„์ ๋ช…^__^/dist/index.js:87
            throw new Error(`์šฐ์œ  ๋ถ€์กฑ!!! ํ˜„์žฌ ๋ณด์œ  ์šฐ์œ ๋Ÿ‰ : ${this.milk}`);
            ^

Error: ์šฐ์œ  ๋ถ€์กฑ!!! ํ˜„์žฌ ๋ณด์œ  ์šฐ์œ ๋Ÿ‰ : 0

 

 

 

 

 

 

 

 

728x90