Post

๐ŸŽจ 03. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

๐ŸŽจ 03. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

โ˜•ย ์ดˆ๋Œ€ํ˜• ์ปคํ”ผ ์ „๋ฌธ์ , ์Šคํƒ€๋ฒ„์ฆˆ

๋‹จ๊ธฐ๊ฐ„์— ํญ๋ฐœ์ ์œผ๋กœ ์„ฑ์žฅํ•œ ์Šคํƒ€๋ฒ„์ฆˆ ์นดํŽ˜๋Š” ๋‹ค์–‘ํ•œ ์Œ๋ฃŒ๋ฅผ ๋ชจ๋‘ ํฌ๊ด„ํ•˜๋Š” ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์„ ๊ฐ–์ถ”์ง€ ๋ชปํ–ˆ๋‹ค. ์‚ฌ์—…์ด ์•ˆ์ •ํ™”๋œ ์ง€๊ธˆ์—์„œ์•ผ ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์„ ๊ฐœ์„ ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋Š” ์ค‘์ธ๋ฐ, ์‚ฌ์—…์„ ์‹œ์ž‘ํ•  ๋ฌด๋ ต ๋งŒ๋“ค์–ด์ง„ ์ฃผ๋ฌธ ์‹œ์Šคํ…œ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋˜์—ˆ๋‹ค.

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
32
33
34
35
36
37
38
39
40
41
// ์Œ๋ฃŒ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ถ”์ƒ ํด๋ž˜์Šค
abstract class Beverage {
  protected description: string = "์•Œ ์ˆ˜ ์—†๋Š” ์Œ๋ฃŒ";

  getDescription(): string {
    return this.description;
  }

  // cost()๋Š” ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ
  abstract cost(): number;
}

// ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ ์„œ๋ธŒํด๋ž˜์Šค
class DarkRoast extends Beverage {
  constructor() {
    super();
    this.description = "๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ";
  }

  cost(): number {
    return 2.99;
  }
}

// ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ ์„œ๋ธŒํด๋ž˜์Šค
class HouseBlend extends Beverage {
  constructor() {
    super();
    this.description = "๋ถ€๋“œ๋Ÿฌ์šด ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ";
  }

  cost(): number {
    return 2.49;
  }
}

// ์‚ฌ์šฉ ์˜ˆ์ œ
const myCoffee: Beverage = new DarkRoast();
console.log(myCoffee.getDescription()); // ๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ
console.log(`๊ฐ€๊ฒฉ: $${myCoffee.cost()}`); // ๊ฐ€๊ฒฉ: $2.99

  • Beverage๋Š” ์Œ๋ฃŒ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์ด๋ฉฐ ๋งค์žฅ์—์„œ ํŒ๋งค๋˜๋Š” ๋ชจ๋“  ์Œ๋ฃŒ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๋จ.
  • description์ด๋ผ๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ๊ฐ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์„ค์ •๋˜๋ฉฐ, ๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๋‚ด์šฉ์€ getDescription() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ.
  • cost() ๋ฉ”์†Œ๋“œ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ, ๋ชจ๋“  ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์Œ๋ฃŒ์˜ ๊ฐ€๊ฒฉ์„ ๋ฆฌํ„ดํ•˜๋Š” cost() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ƒˆ๋กœ ์ •์˜ํ•ด์•ผ ํ•จ.

๊ณ ๊ฐ์€ ์ปคํ”ผ๋ฅผ ์ฃผ๋ฌธํ•  ๋•Œ ์šฐ์œ ๋‚˜ ๋‘์œ , ๋ชจ์นด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ทธ ์œ„์— ํœ˜ํ•‘ํฌ๋ฆผ์„ ์–น๊ธฐ๋„ ํ•œ๋‹ค. ๊ฐ๊ฐ์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์ปคํ”ผ ๊ฐ€๊ฒฉ์ด ์˜ฌ๋ผ๊ฐ€์•ผ ํ•˜๊ธฐ์— ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ด๋Ÿฐ ์ ์„ ๋ชจ๋‘ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.

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
32
33
34
35
36
37
38
39
40
41
42
43
class DarkRoast {
  description: string = "๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ";

  cost(): number {
    return 2.99;
  }
}

class HouseBlend {
  description: string = "๋ถ€๋“œ๋Ÿฌ์šด ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ";

  cost(): number {
    return 2.49;
  }
}

// ๐Ÿ’ฅ: ์กฐํ•ฉ๋ณ„๋กœ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ
class DarkRoastWithMilk {
  description: string = "๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ + ์šฐ์œ ";

  cost(): number {
    return 2.99 + 0.50;
  }
}

class DarkRoastWithMilkAndWhip {
  description: string = "๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ + ์šฐ์œ  + ํœ˜ํ•‘ํฌ๋ฆผ";

  cost(): number {
    return 2.99 + 0.50 + 0.60;
  }
}

class HouseBlendWithMocha {
  description: string = "๋ถ€๋“œ๋Ÿฌ์šด ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ + ์ดˆ์ฝœ๋ฆฟ";

  cost(): number {
    return 2.49 + 0.70;
  }
}
.
.
.

โ“ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋””์ž์ธ ์›์น™ ์ค‘ ๋ฌด์—‡์„ ์ง€ํ‚ค์ง€ ์•Š๊ณ  ์žˆ์„๊นŒ?

๐Ÿ’ก ๋””์ž์ธ ์›์น™ 1: ๋ณ€ํ•˜๋Š” ๋ถ€๋ถ„์„ ์บก์Аํ™”ํ•˜๋ผ

  • ์šฐ์œ  ๊ฐ€๊ฒฉ, ์ถ”๊ฐ€ ์˜ต์…˜(ํœ˜ํ•‘ํฌ๋ฆผ, ์ดˆ์ฝœ๋ฆฟ ๋“ฑ)์€ ๋ณ€ํ•˜๋Š” ์š”์†Œ์ธ๋ฐ, ์ด๊ฑธ cost() ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ์ง์ ‘ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๊ณ  ์žˆ์Œ.

๐Ÿ’ก ๋””์ž์ธ ์›์น™ 2: ์ƒ์†๋ณด๋‹ค๋Š” ๊ตฌ์„ฑ(Composition)์„ ํ™œ์šฉํ•˜๋ผ

  • ํ˜„์žฌ ๊ตฌ์กฐ๋Š” DarkRoastWithMilkAndCaramel ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ๊ณ„์† ์ƒ์†ํ•ด์„œ ๋งŒ๋“ค๊ณ  ์žˆ์Œ.

๐Ÿ’ก ๋””์ž์ธ ์›์น™ 3: ํด๋ž˜์Šค๋Š” ํ™•์žฅ์—๋Š” ์—ด๋ ค ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ, ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค. (OCP - ๊ฐœ๋ฐฉ/ํ์‡„ ์›์น™)

  • ์šฐ์œ  ๊ฐ€๊ฒฉ์ด ๋ฐ”๋€Œ๊ฑฐ๋‚˜, ์ƒˆ๋กœ์šด ์žฌ๋ฃŒ(์บ๋Ÿฌ๋ฉœ ๋“ฑ)๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ,๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ตฌ์กฐ์ด๋ฏ€๋กœ OCP ์›์น™์„ ์–ด๊ธฐ๊ณ  ์žˆ์Œ.

์ธ์Šคํ„ด์ˆ˜ ๋ณ€์ˆ˜์™€ ์Šˆํผํด๋ž˜์Šค ์ƒ์†์„ ์จ์„œ ์ฒจ๊ฐ€๋ฌผ์„ ๊ด€๋ฆฌํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?

๐Ÿ“Œย Beverage ํด๋ž˜์Šค (์Œ๋ฃŒ ๊ธฐ๋ณธ ํด๋ž˜์Šค)

  • description: ์Œ๋ฃŒ ์„ค๋ช…์„ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜ (์˜ˆ: โ€œ๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผโ€)
  • hasMilk, hasSoy, hasMocha, hasWhip: ์ฒจ๊ฐ€๋ฌผ์ด ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ €์žฅํ•˜๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’
  • setMilk(), setSoy(), setMocha(), setWhip(): ์ฒจ๊ฐ€๋ฌผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฉ”์†Œ๋“œ
  • cost(): ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ถ”๊ฐ€ ๋น„์šฉ์„ ๋”ํ•  ์ˆ˜ ์žˆ์Œ
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
32
33
34
35
36
37
38
39
class Beverage {
  description: string = "์•Œ ์ˆ˜ ์—†๋Š” ์Œ๋ฃŒ";
  hasMilk: boolean = false;
  hasSoy: boolean = false;
  hasMocha: boolean = false;
  hasWhip: boolean = false;

  getDescription(): string {
    return this.description;
  }

  setMilk(): void {
    this.hasMilk = true;
  }
  setSoy(): void {
    this.hasSoy = true;
  }
  setMocha(): void {
    this.hasMocha = true;
  }
  setWhip(): void {
    this.hasWhip = true;
  }

  cost(): number {
    let totalCost = 0;

    // ์Œ๋ฃŒ ๊ธฐ๋ณธ ๊ฐ€๊ฒฉ (์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์„ค์ •)
    totalCost += this.getBaseCost();

    // ์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ ์ถ”๊ฐ€
    if (this.hasMilk) totalCost += 0.50;
    if (this.hasSoy) totalCost += 0.60;
    if (this.hasMocha) totalCost += 0.70;
    if (this.hasWhip) totalCost += 0.60;

    return totalCost;
  }
}

๐Ÿ“Œ DarkRoast & HouseBlend ํด๋ž˜์Šค (์Œ๋ฃŒ ์ข…๋ฅ˜๋ณ„ ํด๋ž˜์Šค)

  • DarkRoast์™€ HouseBlend ํด๋ž˜์Šค๋Š” Beverage ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์Œ.
  • Beverage ํด๋ž˜์Šค์—์„œ cost()๋ฅผ ๊ธฐ๋ณธ ๊ตฌํ˜„ (์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ๋งŒ ๊ณ„์‚ฐ)
  • ์„œ๋ธŒํด๋ž˜์Šค(DarkRoast, HouseBlend)์—์„œ๋Š” ๊ธฐ๋ณธ ๊ฐ€๊ฒฉ๋งŒ ์„ค์ •ํ•˜๊ณ , super.cost() ํ˜ธ์ถœ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class DarkRoast extends Beverage {
  constructor() {
    super();
    this.description = "๊ฐ€์žฅ ํ›Œ๋ฅญํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ";
  }

  cost(): number {
    return 2.99 + super.cost(); // ๊ธฐ๋ณธ ๊ฐ€๊ฒฉ + ์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ
  }
}

class HouseBlend extends Beverage {
  constructor() {
    super();
    this.description = "๋ถ€๋“œ๋Ÿฌ์šด ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ";
  }

  cost(): number {
    return 2.49 + super.cost(); // ๊ธฐ๋ณธ ๊ฐ€๊ฒฉ + ์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ
  }
}

์ด ํ”„๋กœ์ ํŠธ์—์„œ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ ๋””์ž์ธ์— ์˜ํ–ฅ์„ ๋ฏธ์น  ๋งŒํ•œ ์š”์†Œ๋ฅผ ์ ์–ด๋ณด์ž.

  • ์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
    • ์ฒจ๊ฐ€๋ฌผ ๊ฐ€๊ฒฉ์ด ๋ฐ”๋€Œ๋ฉด Beverage ํด๋ž˜์Šค์˜ cost() ๋ฉ”์„œ๋“œ์—์„œ ์ง์ ‘ ์ˆ˜์ •ํ•ด์•ผ ํ•จ.
    • ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง. ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ฐ€๊ฒฉ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Œ.
  • ์ฒจ๊ฐ€๋ฌผ์˜ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์ƒˆ๋กœ์šด ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๊ณ , ์Šˆํผํด๋ž˜์Šค์˜ cost() ๋ฉ”์†Œ๋“œ๋„ ๊ณ ์ณ์•ผ ํ•œ๋‹ค.
    • ์ƒˆ๋กœ์šด ์ฒจ๊ฐ€๋ฌผ์ด ์ถ”๊ฐ€๋˜๋ฉด setMilk(), setSoy() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง.
    • ์ฒจ๊ฐ€๋ฌผ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์Šˆํผํด๋ž˜์Šค cost() ๋ฉ”์„œ๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง.
  • ์ƒˆ๋กœ์šด ์Œ๋ฃŒ๊ฐ€ ์ถœ์‹œ๋  ์ˆ˜๋„ ์žˆ๋‹ค. ํŠน์ • ์ฒจ๊ฐ€๋ฌผ์ด ๋“ค์–ด๊ฐ€๋ฉด ์•ˆ ๋˜๋Š” ์Œ๋ฃŒ๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
    • ์Œ๋ฃŒ ๋ณ„๋กœ ์ฒจ๊ฐ€๋ฌผ์ด ์ œํ•œ๋  ์ˆ˜ ์žˆ์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด, ์–ด๋–ค ์Œ๋ฃŒ๋Š” ์šฐ์œ ๋‚˜ ๋‘์œ ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†์„ ์ˆ˜ ์žˆ์Œ.
    • Beverage ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ œ์•ฝ์ด ๋งŽ์•„์ง€๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค์–ด์ง.
  • ๊ณ ๊ฐ์ด ๋”๋ธ” ๋ชจ์นด๋ฅผ ์ฃผ๋ฌธํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ๋ ๊นŒ?
    • ๋”๋ธ” ๋ชจ์นด๋Š” ๋ชจ์นด๋ฅผ ๋‘ ๋ฒˆ ๋„ฃ๋Š” ์˜ต์…˜์ด๋ฏ€๋กœ, ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด cost() ๋ฉ”์„œ๋“œ๊ฐ€ ํ™•์žฅ๋  ํ•„์š” ์žˆ์Œ.
    • ๋งŒ์•ฝ ๋ชจ์นด ์ถ”๊ฐ€๊ฐ€ ๋‘ ๋ฒˆ ์ด์ƒ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, setMocha() ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ cost() ๋ฉ”์„œ๋“œ๋ฅผ ๋” ๋ณต์žกํ•˜๊ฒŒ ์ž‘์„ฑํ•ด์•ผ ํ•จ.
  • ์ƒˆ๋กœ์šด ์ฒจ๊ฐ€๋ฌผ ์˜ต์…˜์„ ๋„์ž…ํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค, ๋ชจ๋“  ์Œ๋ฃŒ ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, ์บ๋Ÿฌ๋ฉœ์ด๋‚˜ ์‹œ๋Ÿฝ ๊ฐ™์€ ์ƒˆ๋กœ์šด ์ฒจ๊ฐ€๋ฌผ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค, ๊ฐ ์Œ๋ฃŒ ํด๋ž˜์Šค์—์„œ ์ด๋ฅผ ๋‹ค๋ฃจ๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.
    • ์ด๋กœ ์ธํ•ด ๊ฐ์ฒด์ง€ํ–ฅ ์›์น™์ธ ๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™(OCP)์„ ์œ„๋ฐ˜ํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ˆ˜์ •์˜ ๋ฒ”์œ„๊ฐ€ ์ปค์ง€๋ฏ€๋กœ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.
  • ๊ธฐ๋ณธ ์Œ๋ฃŒ ๊ฐ€๊ฒฉ์„ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ํ• ์ธ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ, ๋ชจ๋“  ์Œ๋ฃŒ ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
    • ์Œ๋ฃŒ์˜ ๊ธฐ๋ณธ ๊ฐ€๊ฒฉ์— ๋ณ€๋™์ด ์ƒ๊ธฐ๋ฉด ๊ฐ ์Œ๋ฃŒ ํด๋ž˜์Šค์—์„œ ๊ฐ€๊ฒฉ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์ด์ง€ ์•Š์Œ.
    • ํ• ์ธ์ด๋‚˜ ํ”„๋กœ๋ชจ์…˜ ๊ฐ€๊ฒฉ์„ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด, ๊ฐ๊ฐ์˜ ์Œ๋ฃŒ ํด๋ž˜์Šค์—์„œ ์ด๋ฅผ ์ ์šฉํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ•˜๋ฏ€๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๋ฒˆ๊ฑฐ๋กญ๋‹ค.
  • ์Œ๋ฃŒ์˜ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉด Beverage ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ์„œ๋ธŒํด๋ž˜์Šค๋“ค์ด ๋งŽ์•„์ง€๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ๋ณต์žกํ•ด์ง„๋‹ค.
    • ์Œ๋ฃŒ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„์ง€๋ฉด DarkRoast, HouseBlend ๊ฐ™์€ ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๋งŽ์•„์ง€๊ณ , ์ด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง.
    • ์ƒ์† ๊ตฌ์กฐ๊ฐ€ ๊นŠ์–ด์ง€๊ฑฐ๋‚˜ ๋งŽ์€ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.
  • ๊ฐ ์Œ๋ฃŒ์˜ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ ๋กœ์ง์ด ์ค‘๋ณต๋œ๋‹ค.
    • ๊ฐ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ cost() ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋งˆ๋‹ค ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ, ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋ฐœ์ƒ.
    • ์ด๋กœ ์ธํ•ด ์ƒˆ๋กœ์šด ์Œ๋ฃŒ๋‚˜ ์ฒจ๊ฐ€๋ฌผ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ ๋กœ์ง์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์ƒ๊น€.

โ˜•ย OCP ์‚ดํŽด๋ณด๊ธฐ

OCP(OPEN-CLOSED PRINCIPLE)๋Š” ์ •๋ง ์ค‘์š”ํ•œ ๋””์ž์ธ ์›์น™ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

ํด๋ž˜์Šค๋Š” ํ™•์žฅ์—๋Š” ์—ด๋ ค ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ๋Š” ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ํ™•์žฅ์œผ๋กœ ์ƒˆ๋กœ์šด ํ–‰๋™์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ–ˆ์„ ๋•Œ ๋ฌด์—‡์„ ์–ป์„ ์ˆ˜ ์žˆ์„๊นŒ? ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๋•Œ ๊ธ‰๋ณ€ํ•˜๋Š” ์ฃผ๋ณ€ ํ™˜๊ฒฝ์— ์ž˜ ์ ์‘ํ•˜๋Š” ์œ ์—ฐํ•˜๊ณ  ํŠผํŠผํ•œ ๋””์ž์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค!


โ˜•ย ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด ์‚ดํŽด๋ณด๊ธฐ

๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ, ์ผ๋‹จ ํŠน์ • ์Œ๋ฃŒ์—์„œ ์‹œ์ž‘ํ•ด์„œ ์ฒจ๊ฐ€๋ฌผ๋กœ ๊ทธ ์Œ๋ฃŒ๋ฅผ ์žฅ์‹(decorate)ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์ž. ์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋–ค ๊ณ ๊ฐ์ด ๋ชจ์นด์™€ ํœ˜ํ•‘ํฌ๋ฆผ์„ ์ถ”๊ฐ€ํ•œ ๋‹คํฌ ๋กœ์ŠคํŠธ ์ปคํ”ผ๋ฅผ ์ฃผ๋ฌธํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์žฅ์‹ํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. DarkRoast ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  2. Mocha ๊ฐ์ฒด๋กœ ์žฅ์‹ํ•œ๋‹ค.
  3. Whip ๊ฐ์ฒด๋กœ ์žฅ์‹ํ•œ๋‹ค.
  4. cost() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋•Œ ์ฒจ๊ฐ€๋ฌผ์˜ ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ์ผ์€ ํ•ด๋‹น ๊ฐ์ฒด์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ์žฅ์‹ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์ด ๊ณผ์ •์—์„œ ์–ด๋–ค ์‹์œผ๋กœ ์œ„์ž„ํ•  ์ˆ˜ ์žˆ์„๊นŒ?


โ˜•ย ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด ์ ์šฉํ•˜๊ธฐ

Image

  • DarkRoast๋Š” Beverage๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์œผ๋ฏ€๋กœ ์Œ๋ฃŒ์˜ ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ๊ณ ๊ฐ์ด ๋ชจ์นด๋ฅผ ์ฃผ๋ฌธํ–ˆ์œผ๋ฏ€๋กœ Mocha ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ๊ฐ์ฒด๋กœ DarkRoast๋ฅผ ๊ฐ์‹ผ๋‹ค.
    • Mocha ๊ฐ์ฒด๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์ด๋‹ค. ๊ฐ์ฒด์˜ ํ˜•์‹์€ ๊ฐ์ฒด๊ฐ€ ์žฅ์‹ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜์˜ํ•˜๋Š”๋ฐ(์—ฌ๊ธฐ์„œ๋Š” Beverage), ์—ฌ๊ธฐ์„œ ๋ฐ˜์˜ํ•œ๋‹ค๋Š” ๊ฒƒ์€ โ€œ๊ฐ™์€ ํ˜•์‹์„ ๊ฐ–๋Š”๋‹ค.โ€ ๋ผ๋Š” ๋œป์œผ๋กœ ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.
    • ๋”ฐ๋ผ์„œ Mocha์—๋„ cost() ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๊ณ , Mocha๊ฐ€ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๊ฒƒ๋„ Beverage ๊ฐ์ฒด๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ๋‹ค. Mocha๋„ Beverage์˜ ์„œ๋ธŒํด๋ž˜์Šค ํ˜•์‹์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Image

  • ๊ณ ๊ฐ์ด ํœ˜ํ•‘ํฌ๋ฆผ๋„ ์ถ”๊ฐ€ํ–ˆ์œผ๋‹ˆ๊นŒ Whip ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด Mocha๋ฅผ ๊ฐ์‹ผ๋‹ค.
    • Whip๋„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ผ์„œ DarkRoast์˜ ํ˜•์‹์„ ๋ฐ˜์˜ํ•˜๋ฉฐ, cost() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.
    • Mocha์™€ Whip์— ์‹ธ์—ฌ ์žˆ๋Š” DarkRoast๋Š” ์—ฌ์ „ํžˆ Beverage ๊ฐ์ฒด์ด๊ธฐ์— cost() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์„ ๋น„๋กฏํ•œ DarkRoast์— ๊ด€ํ•œ ์ผ์ด๋ผ๋ฉด ๋ฌด์—‡์ด๋“  ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ€๊ฒฉ์„ ๊ตฌํ•  ๋•Œ๋Š” ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ์— ์žˆ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์ธ Whip์˜ cost()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Whip์€ ๊ทธ ๊ฐ์ฒด๊ฐ€ ์žฅ์‹ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์—๊ฒŒ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ์„ ์œ„์ž„ํ•œ๋‹ค. ๊ฐ€๊ฒฉ์ด ๊ตฌํ•ด์ง€๊ณ  ๋‚˜๋ฉด, ๊ณ„์‚ฐ๋œ ๊ฐ€๊ฒฉ์— ํœ˜ํ•‘ํฌ๋ฆผ์˜ ๊ฐ€๊ฒฉ์„ ๋”ํ•œ ๋‹ค์Œ ๊ทธ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฆฌํ„ดํ•œ๋‹ค.

โ—์ •๋ฆฌ

  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ์Šˆํผํด๋ž˜์Šค๋Š” ์ž์‹ ์ด ์žฅ์‹ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์˜ ์Šˆํผํด๋ž˜์Šค์™€ ๊ฐ™๋‹ค.
  • ํ•œ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ๊ฐ์Œ€ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ž์‹ ์ด ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์™€ ๊ฐ™์€ ์Šˆํผํด๋ž˜์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ์— ์›๋ž˜ ๊ฐ์ฒด(์‹ธ์—ฌ ์žˆ๋Š” ๊ฐ์ฒด)๊ฐ€ ๋“ค์–ด๊ฐˆ ์ž๋ฆฌ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด๋„ ์ƒ๊ด€์—†๋‹ค.
  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ž์‹ ์ด ์žฅ์‹ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์—๊ฒŒ ์–ด๋–ค ํ–‰๋™์„ ์œ„์ž„ํ•˜๋Š” ์ผ ๋ง๊ณ ๋„ ์ถ”๊ฐ€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด๋Š” ์–ธ์ œ๋“ ์ง€ ๊ฐ์Œ€ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์‹คํ–‰ ์ค‘์— ํ•„์š”ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โ˜•ย ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ์ •์˜

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด(Decorator Pattern)์œผ๋กœ ๊ฐ์ฒด์— ์ถ”๊ฐ€ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ๋”ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ๋ณด๋‹ค ํ›จ์”ฌ ์œ ์—ฐํ•˜๊ฒŒ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

Image

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

โ˜•ย Beverage ํด๋ž˜์Šค ์žฅ์‹ํ•˜๊ธฐ

Image

  • HouseBlend, Espresso, DarkRoast, Decaf: ์ปคํ”ผ ์ข…๋ฅ˜๋งˆ๋‹ค ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ตฌ์ƒ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค์—ˆ๋‹ค.
  • Milk, Mocha, Soy, Whip: ๊ฐ๊ฐ์˜ ์ฒจ๊ฐ€๋ฌผ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ. cost()์™€ getDescription()๋„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

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

๊ทธ๋ ‡๋‹ค๋ฉด ํ–‰๋™์€ ์–ด๋””์„œ ์˜ฌ๊นŒ?

์–ด๋–ค ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ ์ƒˆ๋กœ์šด ํ–‰๋™์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ƒˆ๋กœ์šด ํ–‰๋™์€ ์Šˆํผํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ํ–‰๋™์„ ์ƒ์†๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ์ฒด๋ฅผ _๊ตฌ์„ฑ_ํ•ด์„œ ์–ป๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์Œ๋ฃŒ์— ์ฒจ๊ฐ€๋ฌผ์„ ๋‹ค์–‘ํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•ด๋„ ์œ ์—ฐ์„ฑ์„ ์žƒ์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ์˜ ํ˜•์‹๋งŒ ์ƒ์†ํ•˜๋ฉด ๋˜๋Š” ๊ฑฐ๋ผ๋ฉด Beverage ํด๋ž˜์Šค๋ฅผ ์™œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์—ˆ์„๊นŒ?

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


โ˜•ย ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด ์ ์šฉ ์—ฐ์Šต

โ€œ๋‘์œ ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํœ˜ํ•‘ํฌ๋ฆผ์„ ์–น์€ ๋”๋ธ” ๋ชจ์นด ํ•œ ์ž” ์ฃผ์„ธ์š”!โ€
์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ข‹์„์ง€ ๊ทธ๋ ค ๋ณด์ž.

Image

  • ์ œ์ผ ๋จผ์ € Whip์˜ cost() ํ˜ธ์ถœ
  • Whip์—์„œ Mocha์— ์žˆ๋Š” cost() ํ˜ธ์ถœ
  • Mocha์—์„œ ๊ทธ ์•ˆ์ชฝ์— ์žˆ๋Š” ๋‹ค๋ฅธ Mocha์˜ cost() ํ˜ธ์ถœ
  • Mocha์—์„œ Soy์— ์žˆ๋Š” cost() ํ˜ธ์ถœ
  • ๋งˆ์ง€๋ง‰ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์ธ Soy์—์„œ DarkRoast์˜ cost() ํ˜ธ์ถœ

Image

  • DarkRoast์˜ cost()์—์„œ 89์„ผํŠธ ๋ฆฌํ„ด. โ€” cost() ๋ฉ”์†Œ๋“œ๋Š” ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋จ.
  • Soy์˜ cost()์—์„œ 89์„ผํŠธ + 15์„ผํŠธ ๋ฆฌํ„ด. โ€” cost() ๋ฉ”์†Œ๋“œ๋Š” ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋จ.
  • Mocha์˜ cost()์—์„œ 89์„ผํŠธ + 15์„ผํŠธ + 20์„ผํŠธ ๋ฆฌํ„ด. โ€” cost() ๋ฉ”์†Œ๋“œ๋Š” ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋จ.
  • Mocha์˜ cost()์—์„œ 89์„ผํŠธ + 15์„ผํŠธ + 20์„ผํŠธ + 20์„ผํŠธ ๋ฆฌํ„ด. โ€” cost() ๋ฉ”์†Œ๋“œ๋Š” ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋จ.
  • Whip์˜ cost()์—์„œ 89์„ผํŠธ + 15์„ผํŠธ + 20์„ผํŠธ + 20์„ผํŠธ + 10์„ผํŠธ ๋ฆฌํ„ด. โ€” cost() ๋ฉ”์†Œ๋“œ๋Š” ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋จ.

โ˜•ย ์ปคํ”ผ ์ฃผ๋ฌธ ์‹œ์Šคํ…œ ์ฝ”๋“œ ๋งŒ๋“ค๊ธฐ

โœ…ย ๋ฒ ์ด์Šค ํด๋ž˜์Šค ์ค€๋น„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1๏ธโƒฃ ์Œ๋ฃŒ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค (์ถ”์ƒ ํด๋ž˜์Šค)
abstract class Beverage {
  protected description: string = "์•Œ ์ˆ˜ ์—†๋Š” ์Œ๋ฃŒ";

  getDescription(): string {
    return this.description;
  }

  abstract cost(): number;
}

// 2๏ธโƒฃ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋ณธ ํด๋ž˜์Šค (Beverage๋ฅผ ํ™•์žฅํ•˜๋Š”๋ฐ, ์Œ๋ฃŒ๋ฅผ ๊ฐ์Œ€ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ฆ)
abstract class CondimentDecorator extends Beverage {
  abstract getDescription(): string;
}

โœ…ย ์Œ๋ฃŒ ์ฝ”๋“œ ๊ตฌํ˜„

  • ์Œ๋ฃŒ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์ž์—ด์„ ์„ค์ •ํ•˜๊ณ  cost() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ผญ! ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 3๏ธโƒฃ ์‹ค์ œ ์Œ๋ฃŒ ์„œ๋ธŒํด๋ž˜์Šค (๋‹คํฌ ๋กœ์ŠคํŠธ, ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ)
class Espresso extends Beverage {
  constructor() {
    super();
    this.description = "์—์Šคํ”„๋ ˆ์†Œ";
  }

  cost(): number {
    return 1.99;
  }
}

class HouseBlend extends Beverage {
  constructor() {
    super();
    this.description = "ํ•˜์šฐ์Šค ๋ธ”๋ Œ๋“œ ์ปคํ”ผ";
  }

  cost(): number {
    return 0.89;
  }
}

โœ…ย ์ฒจ๊ฐ€๋ฌผ ์ฝ”๋“œ ๊ตฌํ˜„ํ•˜๊ธฐ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 4๏ธโƒฃ ๊ตฌ์ฒด์ ์ธ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ (ํœ˜ํ•‘ํฌ๋ฆผ, ์šฐ์œ , ์ƒท ์ถ”๊ฐ€ ๋“ฑ)
class Mocha extends CondimentDecorator {
  constructor(private beverage: Beverage) {
    super();
  }

  getDescription(): string {
    return this.beverage.getDescription() + ", ๋ชจ์นด";
  }

  cost(): number {
    return this.beverage.cost() + 0.20;
  }
}

โœ…ย ์ปคํ”ผ ์ฃผ๋ฌธ ์‹œ์Šคํ…œ ์ฝ”๋“œ ํ…Œ์ŠคํŠธ

1
2
3
4
5
6
7
8
9
10
// 5๏ธโƒฃ ์‚ฌ์šฉ ์˜ˆ์ œ
let myCoffee: Beverage = new Espresso();  // ์—์Šคํ”„๋ ˆ์†Œ ์ฃผ๋ฌธ
console.log(myCoffee.getDescription() + `: $${myCoffee.cost()}`);  
// "์—์Šคํ”„๋ ˆ์†Œ: $1.99"

myCoffee = new Mocha(myCoffee);  // Mocha๋กœ ๊ฐ์‹ธ๊ธฐ
myCoffee = new Mocha(myCoffee);  // Mocha ์ƒท ์ถ”๊ฐ€
myCoffee = new Whip(myCoffee);   // Whip์œผ๋กœ ๊ฐ์‹ธ๊ธฐ
console.log(myCoffee.getDescription() + `: $${myCoffee.cost()}`);  
// "์—์Šคํ”„๋ ˆ์†Œ, ๋ชจ์นด, ๋ชจ์นด, ํœ˜ํ•‘ํฌ๋ฆผ: $4.29"
This post is licensed under CC BY 4.0 by the author.