๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์ด๋ž€?

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

์นดํŽ˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ๋ฌธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ข€ ๋” ํ™•์žฅ์„ฑ ์žˆ๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณด์ž.

์š”๊ตฌ์‚ฌํ•ญ

  1. ํ•ด๋‹น ์นดํŽ˜๋Š” ๊ธ‰์†๋„๋กœ ์„ฑ์žฅ์„ ์ด์–ด๊ฐ€๊ณ  ์žˆ๋Š” ์นดํŽ˜์ด๊ธฐ์— ๋ฉ”๋‰ด์˜ ๋ณ€๋™์ด ๋งŽ๋‹ค.
  2. ์ปคํ”ผ๋ฅผ ์ฃผ๋ฌธํ•  ๋•Œ๋Š” ๋‘์œ , ์ŠคํŒ€ ์šฐ์œ , ๋ชจ์นด, ํœ˜ํ•‘ ํฌ๋ฆผ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ๋ฉ”๋‰ด๋กœ ๊ตฌ์„ฑํ•œ๋‹ค.
  3. ๋ชจ๋“  ๋ฉ”๋‰ด๋“ค์€ cost()๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
  4. ํ˜„์žฌ ๊ธฐ์กด ์‹œ์Šคํ…œ์˜ ๊ตฌ์„ฑ๋„์˜ ์ผ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๊ธฐ์กด ์‹œ์Šคํ…œ์˜ ๋ฌธ์ œ์ 

  1. ์œ„์˜ ๊ตฌ์„ฑ๋„์—๋Š” 4๊ฐ€์ง€ ๋ฉ”๋‰ด ๋ฐ–์— ์—†์–ด ๋‹จ์ˆœํ•ด๋ณด์ด์ง€๋งŒ ๋งŒ์•ฝ ์ˆ˜๋งŽ์€ ์ฒจ๊ฐ€๋ฌผ ๋ฉ”๋‰ด, ์ˆ˜๋งŽ์€ ๋ฉ”๋‰ด๋“ค์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด ๋ช‡์‹ญ, ๋ช‡๋ฐฑ๊ฐ€์ง€์˜ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.
  2. ์‹ฌ์ง€์–ด ํŠน์ • ์ฒจ๊ฐ€๋ฌผ ๋ฉ”๋‰ด์˜ ๊ฐ€๊ฒฉ์ด ์˜ค๋ฅด๋ฉด..? ๋ช‡์‹ญ, ๋ช‡๋ฐฑ๊ฐ€์ง€์˜ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒํ• ์ˆ˜๋„ ์žˆ๋‹ค.
  3. ์ฒจ๊ฐ€๋ฌผ ๋ฉ”๋‰ด์˜ ์ข…๋ฅ˜๊ฐ€ ํ•˜๋‚˜๋งŒ ์ฆ๊ฐ€ํ•ด๋„ ํด๋ž˜์Šค๋Š” ํญ๋ฐœ์ ์œผ๋กœ ์ฆ๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ด ๋ฐฉ์‹์€ ์–ด๋–จ๊นŒ?

  1. Beverage๊ฐ€ ๋ชจ๋“  ์ฒจ๊ฐ€๋ฌผ์˜ ์กด์žฌ ์œ ๋ฌด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.
  2. ๊ฐ ๋ฉ”๋‰ด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค๋Š” Beverage๋ฅผ ์ƒ์†๋ฐ›์€ ํ›„ cost()๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์Šˆํผ ํด๋ž˜์Šค Beverage์˜ cost()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
  3. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๋ฉด ๋‹จ์ˆœํžˆ ๋ฉ”๋‰ด์˜ ๊ฐฏ์ˆ˜๋งŒํผ๋งŒ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ...
  4. ๋งŒ์•ฝ ์ฒจ๊ฐ€๋ฌผ ๋ฉ”๋‰ด์˜ ๊ฐ€๊ฒฉ์ด ๋ณ€๊ฒฝ๋˜๋ฉด..?, ์ฒจ๊ฐ€๋ฌผ ์ข…๋ฅ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉด Beverage๋ฅผ ๊ณ„์† ์ˆ˜์ •ํ•ด์•ผํ•œ๋‹ค.
  5. OCP ์›์น™์„ ์ง€ํ‚ค์ง€ ์•Š๊ณ  ์žˆ๋‹ค.

์ฐธ๊ณ ) OCP๋ž€?

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

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ด์šฉํ•˜์—ฌ OCP ์›์น™์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•ด๋ณด์ž.

  1. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ ์ถ”๊ฐ€ ๋กœ์ง์„ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํŒจํ„ด์ด๋‹ค.
  2. ๋”ฐ๋ผ์„œ ์œ„์™€ ๊ฐ™์€ ์š”๊ตฌ์‚ฌํ•ญ์—์„œ ์†์‰ฝ๊ฒŒ ์ฒจ๊ฐ€๋ฌผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ์ •๋ฆฌํ•˜์ž๋ฉด ์ถ”๊ฐ€๋˜๋Š” ๋ฉ”๋‰ด๊ฐ€ ๊ธฐ์กด์˜ ๋ฉ”๋‰ด๋“ค์„ ๊ฐ์‹ธ๋Š” ํ˜•์‹์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ •ํ™•ํžˆ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์„๋• ๊ฐœ๋ฐœ์ž๋“ค์€ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ๋ณด๋Š”๊ฒŒ ์ตœ๊ณ ๋‹ค.
ํ•œ๋ฒˆ ์œ„์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“  ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ ์šฉํ•œ ๊ตฌํ˜„ ๋ฐฉ์‹

public abstract class Beverage {
    String description = "์ œ๋ชฉ ์—†์Œ";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

// Beverage ํ˜•ํƒœ์˜ ๋ณ€์ˆ˜์— ์‚ฝ์ž…๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์† ํ™œ์šฉ
public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();
}
  1. ๊ฐ๊ฐ ๋ฉ”๋‰ด์™€ ์ฒจ๊ฐ€๋ฌผ๋“ค์ด ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์ด๋‹ค.
  2. ์ƒ์†์„ ์ด์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋‹จ์ˆœํžˆ Beverage ๋ณ€์ˆ˜์— ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•ด ์ƒ์†๋ฐ›๋Š” ๊ฒƒ์ด๋‹ค.
/*
 * HouseBlend ์ปคํ”ผ ํด๋ž˜์Šค
 */
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "ํ•˜์šฐ์Šค ๋ธ”๋žœ๋“œ ์ปคํ”ผ";
    }

    public double cost() {
        return 0.89;
    }
}

public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", ๋ชจ์นด";
    }

    /**
     * Mocha๊ฐ€ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” beverage์˜ ๊ฐ€๊ฒฉ ๋กœ์ง + ๋ณธ์ธ์˜ ์„ธ๋ถ€ ๋กœ์ง์„ ํ•ฉ์นœ๋‹ค.
     */
    @Override
    public double cost() {
        return 0.20 + beverage.cost();
    }
}
  1. ๊ฐ๊ฐ HouseBlend ๋ฉ”๋‰ด ๊ตฌํ˜„ ํด๋ž˜์Šค์™€ Mocha ์ฒจ๊ฐ€๋ฌผ ๊ตฌํ˜„ ํด๋ž˜์Šค์ด๋‹ค.
  2. Mocha๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํด๋ž˜์Šค๋กœ์„œ ๋กœ์ง์—์„œ ํ˜ธ์ถœํ•  Beverage ํ˜•ํƒœ์˜ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  3. ํ›„์— ์‹คํ–‰ ์‹œ์ ์— Beverage ๋ณ€์ˆ˜์— ํŠน์ • ๊ฐ์ฒด๊ฐ€ ์‚ฝ์ž…๋˜๊ฒŒ ๋œ๋‹ค.
public class DecoratorSimulation {
    public static void main(String[] args) {
        Beverage beverage = new HouseBlend();
        beverage = new Mocha(beverage);
        beverage = new Mocha(beverage); // ํ•˜์šฐ์Šค ๋ธ”๋žœ๋“œ ์ปคํ”ผ + ๋ชจ์นด + ๋ชจ์นด
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
    }
}
  1. ๋ฉ”์ธ ๋กœ์ง์ด๋‹ค.
  2. Mocha ์ฒจ๊ฐ€๋ฌผ ๊ตฌํ˜„ ๊ฐ์ฒด๊ฐ€ HouseBlend ๋ฉ”๋‰ด ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ผ๋‹ค.
  3. ๊ทธ๋ฆฌ๊ณ  ์ด์–ด์„œ ์ถ”๊ฐ€๋œ Mocha ์ฒจ๊ฐ€๋ฌผ ๊ตฌํ˜„ ๊ฐ์ฒด๊ฐ€ Mocha๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‹ผ๋‹ค.
  4. ์ด์ œ ํ•ด๋‹น ์Œ๋ฃŒ๋Š” Mocha 2๊ฐœ๋ฅผ ํฌํ•จํ•œ HouseBlend ์Œ๋ฃŒ๊ฐ€ ๋˜์—ˆ๋‹ค.
  5. ๋งˆ์ง€๋ง‰์— berverage.cost()๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ํ˜ธ์ถœ์€ mocha -> mocha -> houseblend ์ˆœ์ด์ง€๋งŒ ์™„๋ฃŒ๋Š” houseblend -> mocha -> mocha ์ˆœ์œผ๋กœ ์™„๋ฃŒ๋œ๋‹ค.
  6. ์ •๋ฆฌํ•˜์ž๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ ๊ธฐ๋ณธ ๋กœ์ง์— ์„ธ๋ถ€ ๋กœ์ง์„ ๋™์ ์œผ๋กœ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ„ด์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ (์ž๋ฐ” I/O)

  1. JAVA.IO ํŒจํ‚ค์ง€์˜ ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ๋ฐ”ํƒ•์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.
  2. ์˜ˆ๋ฅผ ๋“ค์–ด FileInputStream -> BufferedInputStream -> LineNumberInputStream์ด ์žˆ๋Š”๋ฐ LineNumberInputStream์€ ํ–‰๋ฒˆํ˜ธ๋ฅผ ๋ถ™์—ฌ์ฃผ๋Š” ์—ญํ• ์„, BufferedInputStream์€ ๋ฒ„ํผ ์ž…์ถœ๋ ฅ ๊ธฐ๋Šฅ์„ FileInputStream์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด๋“ค์ผ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ณธ ๊ตฌ์„ฑ์š”์†Œ ์—ญํ• ์„ ํ•œ๋‹ค.
  3. ์ฆ‰ ๊ฐ๊ฐ์˜ ํด๋ž˜์Šค๊ฐ€ ์„ธ๋ถ€๋กœ์ง์„ ํ•˜๋‚˜์”ฉ ๋”ํ•ด๊ฐ€๋ฉฐ ํ•˜๋‚˜์˜ ๋กœ์ง์„ ์™„์„ฑ์‹œํ‚ค๊ณ  ์žˆ๋‹ค.   

 

Reference

Head First Design Patterns - (์—๋ฆญ ํ”„๋ฆฌ๋จผ, ์—˜๋ฆฌ์ž๋ฒ ์Šค ํ”„๋ฆฌ๋จผ, ์ผ€์ด์‹œ ์‹œ์—๋ผ, ๋น„ํŠธ ๋ฒ ์ด์ธ ) ์„ ๋ณด๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.