๐Ÿ€ Knowledge/๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„

[๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„] GoF(Gang of Four) ๋””์ž์ธ ํŒจํ„ด(ํ”„๋กœํ† ํƒ€์ž…, ์ถ”์ƒ ํŒฉํ† ๋ฆฌ, ์–ด๋Œ‘ํ„ฐ, ๋ธŒ๋ฆฌ์ง€, ๋ณตํ•ฉ์ฒด, ํผ์‚ฌ๋“œ, ํ”„๋ก์‹œ)

TIlearn 2023. 11. 7. 01:33

Prototype Pattern(ํ”„๋กœํ† ํƒ€์ž…)

 

ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ ํŒจํ„ด์˜ ์ผ์ข…์œผ๋กœ ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ฅผ ์œ„ํ•œ ํŒจํ„ด์ด๋‹ค.

๊ธฐ์กด์—๋Š” ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ ํ”„๋กœํผํ‹ฐ๋“ค์„ ๋ชจ๋‘ ๋ณต์‚ฌํ•˜์—ฌ, ์ƒˆ๋กญ๊ฒŒ ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ์•ผ ํ–ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ์ฝ”๋“œ๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ์งœ๊ธฐ์— ๊ท€์ฐฎ๋‹ค. ๋˜ํ•œ ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ Private๋กœ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ๋“ค์ด ์žˆ๋‹ค๋ฉด ์™„๋ฒฝํ•˜๊ฒŒ ๋ณต์‚ฌํ•ด๋‚ผ ์ˆ˜ ์—†๋‹ค.

 

์ถœ์ฒ˜ : https://refactoring.guru/ko/design-patterns/prototype

 

 

ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์‚ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ์ฒด๋“ค์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค. ์ฆ‰, ๋ชจ๋“  ๊ฐ์ฒด๋“ค์ด ๊ณตํ†ต์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” "clone" ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

 

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

 

์ด๋ ‡๊ฒŒ ๋ณต์‚ฌ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ”„๋กœํ† ํƒ€์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

 

ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด์˜ ๊ตฌ์กฐ

 

 

์ถœ์ฒ˜ : https://refactoring.guru/ko/design-patterns/prototype

 

 

 

๊ตฌ์กฐ๋Š” ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š๋‹ค. Shape๋Š” clone()์ด๋ผ๋Š” ๊ณตํ†ต ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด Shape์˜ ์ƒ์†์„ ๋ฐ›๋Š” Rectangle๊ณผ Circle์€ ์ด clone ๋ฉ”์„œ๋“œ๋ฅผ ๋˜‘๊ฐ™์ด ๊ฐ€์ง„๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Rectangle๊ณผ Circle์€ ์ž๊ธฐ ์ž์‹ ์˜ ๊ฐ์ฒด๋ฅผ ๋ณต์ œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 

 

 

 

ํ”„๋กœํ†  ํƒ€์ž…์„ C++๋กœ

 

 

Color ํด๋ž˜์Šค

enum class Color {
    kRed,
    kGreen,
    kBlue,
    kWhite,
    kBlack,
};

std::string ColorToString(Color color) {
    switch (color) {
        case Color::kRed:
            return "Red";
        case Color::kGreen:
            return "Green";
        case Color::kBlue:
            return "Blue";
        case Color::kWhite:
            return "White";
        case Color::kBlack:
            return "Black";
        default:
            return "Unknown";
    }
}

 

 

Shape ํด๋ž˜์Šค(ํ”„๋กœํ† ํƒ€์ž…<interface>)

class Shape {
 public:
  Shape(Color color) : color_(color) {}
  virtual Shape* Clone() const = 0;
  virtual std::string ToString() const = 0;

 protected:
  const Color color_;
};

 

 

Rectangle ํด๋ž˜์Šค(ํ”„๋กœํ† ํƒ€์ž… ๊ตฌํ˜„์ฒด1)

class Rectangle : public Shape {
 public:
  Rectangle(Color color, int width, int height)
      : Shape(color), width_(width), height_(height) {}
  Shape* Clone() const override {
    return new Rectangle(color_, width_, height_);
  }
  std::string ToString() const override {
    return "Color: " + ColorToString(color_) +
           ", Width: " + std::to_string(width_) +
           ", Height: " + std::to_string(height_);
  }

 private:
  const int width_;
  const int height_;
};

 

 

Circle ํด๋ž˜์Šค(ํ”„๋กœํ† ํƒ€์ž… ๊ตฌํ˜„์ฒด2)

class Circle : public Shape {
  public:
  Circle(Color color, int radius) : Shape(color), radius_(radius) {}
  Shape* Clone() const { return new Circle(color_, radius_);}
  std::string ToString() const {
    return "Color: " + ColorToString(color_) + ", Radius: " + 
    std::to_string(radius_);
  }
  private:
  const int radius_;
};

 

 

Main ํด๋ž˜์Šค

int main() {
  Shape* shape1 = new Rectangle(Color::kWhite, 3, 2);
  Shape* shape2 = shape1 -> Clone();

  Shape* shape3 = new Circle(Color::kRed, 5);
  Shape* shape4 = shape3 -> Clone();

  std::cout << shape1 << " : " << shape1 -> ToString() << std::endl;
  std::cout << shape2 << " : " << shape2 -> ToString() << std::endl;
  std::cout << shape3 << " : " << shape3 -> ToString() << std::endl;
  std::cout << shape4 << " : " << shape4 -> ToString() << std::endl;
}

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ

0xfb9b10 : Color: White, Width: 3, Height: 2
0xfb9b28 : Color: White, Width: 3, Height: 2
0xfb9b40 : Color: Red, Radius: 5
0xfb9b58 : Color: Red, Radius: 5

 

 

๐Ÿ”ฒ C++์—์„œ์˜ prototype์€ ํ•จ์ˆ˜ ์˜ค๋ฒ„๋กœ๋”ฉ๊ณผ ํ•จ์ˆ˜ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์˜ ๊ณผ์ •์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

 

๐Ÿ”ฒ Shape์˜ virtual ... Clone() ์„ ํ†ตํ•ด์„œ ๊ฐ Rectangle, Circle ์ค‘ ํ•˜๋‚˜์˜ Clone()์ด ์‹คํ–‰๋œ๋‹ค.

 

๐Ÿ”ฒ ์ถœ๋ ฅ ๊ฒฐ๊ณผ Clone()์„ ํ†ตํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์œผ๋ฉฐ, ๊ทธ ๋‚ด์šฉ๋ฌผ์€ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

 


 

 

 

 

 

Abstract Factory Pattern(์ถ”์ƒ ํŒฉํ† ๋ฆฌ)

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ๋Š” ๊ด€๋ จ ๊ฐ์ฒด๋“ค์˜ ๊ตฌ์ƒ ํด๋ž˜์Šค๋“ค์„ ์ง€์ •ํ•˜์ง€ ์•Š๋”๋ผ๋„, ๊ด€๋ จ ๊ฐ์ฒด์˜ ๋ชจ์Œ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ์„ฑ ํŒจํ„ด์ด๋‹ค.

 

๋งŒ์•ฝ์— ์ฃผ๋ฌธ์ž(Client) ๋น…ํ† ๋ฆฌ์•ˆ์‹ ์˜์ž, ์†ŒํŒŒ, ์ปคํ”ผ ํ…Œ์ด๋ธ”์„ ๊ตฌ๋งคํ•˜๊ณ  ์‹ถ์„ ๋•Œ, ๊ตณ์ด ๊ตฌ์ฒด์ ์œผ๋กœ ๋น…ํ† ๋ฆฌ์•ˆ ์‹ ์˜์ž, ๋น…ํ† ๋ฆฌ์•ˆ ์‹ ์†ŒํŒŒ, ๋น…ํ† ๋ฆฌ์•ˆ์‹ ์ปคํ”ผ ํ…Œ์ด๋ธ”์„ ์ฃผ๋ฌธํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

๊ฒฐ๊ตญ ์ฃผ๋ฌธ์ž๋Š” ์–ด๋А ํšŒ์‚ฌ(ํŒฉํ† ๋ฆฌ)์—์„œ ๊ตฌ๋งคํ•  ๊ฒƒ์ธ์ง€ ์ •ํ•ด์•ผ ํ•œ๋‹ค. ๋น…ํ† ๋ฆฌ์•ˆ์‹์œผ๋กœ ๊ฐ ์ œํ’ˆ์„ ํŒ๋งคํ•˜๋Š” ๋น…ํ† ๋ฆฌ์•ˆ ํŒฉํ† ๋ฆฌ, ์•„๋ฅด๋ฐ์ฝ” ์‹์œผ๋กœ ๊ฐ ์ œํ’ˆ์„ ํŒ๋งคํ•˜๋Š” ์•„๋ฅด๋ฐ์ฝ”์‹ ํŒฉํ† ๋ฆฌ, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ˜„๋Œ€์‹ ํŒฉํ† ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž. ์ฃผ๋ฌธ์ž๋Š” ๋น…ํ† ๋ฆฌ์•ˆ ํŒฉํ† ๋ฆฌ์—์„œ์˜ ์ œํ’ˆ๋งŒ์„ ์›ํ•œ๋‹ค๋ฉด ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ๋กœ ๋น…ํ† ๋ฆฌ์•ˆ ํŒฉํ† ๋ฆฌ๋ฅผ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค.

 

์ž ์ด์ œ ๋‹ค์‹œ ๊ทธ ์˜๋ฏธ๋ฅผ ์งš์–ด๋ณด์ž. ์ถ”์ƒ ํŒฉํ† ๋ฆฌ๋ž€, ๊ด€๋ จ ๊ฐ์ฒด(์˜์ž, ์†ŒํŒŒ, ์ปคํ”ผ ํ…Œ์ด๋ธ”)๋“ค์˜ ๊ตฌ์ƒ ํด๋ž˜์Šค(๋น…ํ† ๋ฆฌ์•ˆ์‹ ์˜์ž, ๋น…ํ† ๋ฆฌ์•ˆ ์‹ ์†ŒํŒŒ, ...)๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๋”๋ผ๋„, ๊ด€๋ จ ๊ฐ์ฒด์˜ ๋ชจ์Œ(๋น…ํ† ๋ฆฌ์•ˆ ์‹ ์˜์ž, ๋น…ํ† ๋ฆฌ์•ˆ ์‹....)์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ์„ฑ ํŒจํ„ด์ด๋‹ค.

 

๋‹ค์‹œ๋งํ•ด, ์—ฐ๊ด€์„ฑ ์žˆ๋Š” ์ œํ’ˆ ๊ตฐ์ด ์—ฌ๋Ÿฌ๊ฐœ ์žˆ์„ ๊ฒฝ์šฐ ์ด๋ฅผ ๋ฌถ์–ด ์ถ”์ƒํ™”ํ•˜๊ณ , ๊ตฌ์ฒด์ ์ธ ์ƒํ™ฉ์ด ์ฃผ์–ด์งˆ ๋•Œ ํŒฉํ† ๋ฆฌ ๊ฐ์ฒด์—์„œ ์ง‘ํ•ฉ์œผ๋กœ ๋ฌถ์€ ๊ฐ์ฒด๊ตฐ์„ ๊ตฌํ˜„ํ•˜๋Š” ํŒจํ„ด์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์˜ ํŠน์ง•

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹œ๊ธฐ

 

1๏ธโƒฃ ์ œํ’ˆ์˜ ๊ตฌ์ฒด ํด๋ž˜์Šค์— ์˜์กดํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ(์—ฌ๋Ÿฌ ์ œํ’ˆ๊ตฐ์ด ์žˆ์„ ๊ฒฝ์šฐ)

 

2๏ธโƒฃ ์‹œ์Šคํ…œ ์ƒ์—์„œ ํ•˜๋‚˜์˜ ์ œํ’ˆ ๊ตฐ์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ๋ฅผ ๋“ค์–ด ์• ํ”Œ ์ œํ’ˆ ๊ตฐ์œผ๋กœ ํ†ต์ผ ํ•ด์•ผํ•  ๋•Œ)

 

3๏ธโƒฃ ๊ตฌํ˜„ ๋ถ€๋ถ„ ๋Œ€์‹  ์ธํ„ฐํŽ˜์ด์Šค ๋ถ€๋ถ„๋งŒ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

 


 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ์˜ ์žฅ์ 

 

1๏ธโƒฃ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์™€์˜ ๊ฒฐํ•ฉ์„ฑ์„ ๋‚ฎ์ถค

 

2๏ธโƒฃ ์ œํ’ˆ์„ ์‰ฝ๊ฒŒ ๋Œ€์ฒด ๊ฐ€๋Šฅ

 


 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ์˜ ๋‹จ์ 

 

1๏ธโƒฃ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ๋งŽ์•„์ ธ, ๋ณต์žก๋„๊ฐ€ ์ฆ๊ฐ€

 

2๏ธโƒฃ ์ถ”์ƒ ํด๋ž˜์Šค ๋กœ์ง ์ž์ฒด๋ฅผ ๋ฐ”๊พธ์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น€

 

 

 

 

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์˜ ๊ตฌ์กฐ

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์˜ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ทธ ๊ตฌ์กฐ๋ฅผ ๋ช…ํ™•ํžˆ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/abstract-factory

 

 

 

๐Ÿ”ฒ AbstractFactory : ์ถ”์ƒ ํŒฉํ† ๋ฆฌ๋กœ ์ถ”์ƒ ์ œํ’ˆ๋“ค์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋“ค์˜ ์ง‘ํ•ฉ์„ ์„ ์–ธํ•œ๋‹ค.

 

๐Ÿ”ฒ ConcreteFactory : ๊ตฌ์ƒ ํŒฉํ† ๋ฆฌ๋กœ ์ถ”์ƒ ํŒฉํ† ๋ฆฌ์˜ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๋“ค์„ ๊ตฌํ˜„ํ•œ๋‹ค.

 

๐Ÿ”ฒ AbstractProduct : ์ถ”์ƒ ์ œํ’ˆ์œผ๋กœ ๊ฐ ํƒ€์ž…์˜ ์ œํ’ˆ๋“ค์„ ์ถ”์ƒํ™”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.

 

๐Ÿ”ฒ ConcreteProduct(ProductA, ProductB) : ๊ฐ ํƒ€์ž…์˜ ์ œํ’ˆ ๊ตฌํ˜„์ฒด๋“ค์ด๋‹ค.

 

๐Ÿ”ฒ Client : ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ์ด์šฉํ•˜์—ฌ ์ œํ’ˆ์„ ๋งŒ๋“ ๋‹ค.

 

 

๊ฐ ConcreteFactory(๊ตฌ์ƒ ํŒฉํ† ๋ฆฌ)๋Š” ๊ตฌ์ฒด์ ์ธ ๊ณต์žฅ์œผ๋กœ, ์ œํ’ˆ ๊ตฐ์˜ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‚˜๋‰œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋น…ํ† ๋ฆฌ์•ˆ์‹ ๊ณต์žฅ, ์•„๋ฅด๋ฐ์ฝ”์‹ ๊ณต์žฅ, ํ˜„๋Œ€์‹ ๊ณต์žฅ๋“ฑ์ด ์ด๋Ÿฌํ•œ ConcreteFactory์— ์†ํ•œ๋‹ค.

 

ConcreteFactory ๋ฅผ ํ†ตํ•ด์„œ ConcreteProduct (์ œํ’ˆ ๊ตฌํ˜„์ฒด)๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ConcreteProduct๋Š” ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค๋กœ AbstractProduct ๋ฅผ ๋”ฐ๋ฅด๋Š” ๊ฒƒ ๋ฟ์ด๋‹ค.

 

 

 

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ C++๋กœ

 

 

์ถ”์ƒ ํŒฉํ† ๋ฆฌ(AbstractFactory)

// ์ถ”์ƒ ํŒฉํ† ๋ฆฌ
class FurnitureFactory {
 public:
  virtual Chair* OrderChair() const = 0;
  virtual Table* OrderTable() const = 0;
};

 

 

๊ตฌ์ƒ ํŒฉํ† ๋ฆฌ(ConcreteFactory)

// ๊ตฌ์ƒ ํŒฉํ† ๋ฆฌ1
class ModernFactory : public FurnitureFactory {
 public:
  // ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ง€๋‹˜. ๋ฐ˜ํ™˜ ํƒ€์ž…์€ AbstractProduct
  Chair* OrderChair() const override {
    return new ModernChair();
  }

  Table* OrderTable() const override {
    return new ModernTable();
  }
};

// ๊ตฌ์ƒ ํŒฉํ† ๋ฆฌ2
class AntiqueFactory : public FurnitureFactory {
 public:
  Chair* OrderChair() const override {
    return new AntiqueChair();
  }

  Table* OrderTable() const override {
    return new AntiqueTable();
  }
};

 

 

 

์ถ”์ƒ ์ œํ’ˆ(AbstractProduct)

// ์ถ”์ƒ ์ œํ’ˆ1
class Chair {
 public:
  virtual std::string ToString() const = 0;
};

// ์ถ”์ƒ ์ œํ’ˆ2
class Table {
 public:
  virtual std::string ToString() const = 0;
};

 

 

 

๊ตฌ์ƒ ์ œํ’ˆ(ConcreteProduct)

// ๊ตฌํ˜„์ฒด 1
class ModernChair : public Chair {
 public:
  std::string ToString() const override {
    return "Modern Chair";
  }
};

// ๊ตฌํ˜„์ฒด 2
class ModernTable : public Table {
 public:
  std::string ToString() const override {
    return "Modern Table";
  }
};

// ๊ตฌํ˜„์ฒด 3
class AntiqueChair : public Chair {
 public:
  std::string ToString() const override {
    return "Antique Chair";
  }
};

// ๊ตฌํ˜„์ฒด 4
class AntiqueTable : public Table {
 public:
  std::string ToString() const override {
    return "Antique Table";
  }
};

 

 

์‹คํ–‰ ๋ฉ”์„œ๋“œ ๋ฐ main ํ•จ์ˆ˜

void OrderAndPrint(FurnitureFactory* factory) {
  Chair* chair = factory->OrderChair();
  Table* table = factory->OrderTable();

  std::cout << "Table: " << table->ToString() << ", Chair: " << chair->ToString() << std::endl;
}

int main() {
  ModernFactory modern_factory;
  AntiqueFactory antique_factory;

  OrderAndPrint(&modern_factory);
  OrderAndPrint(&antique_factory);

  return 0;
}

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ

Table: Modern Table, Chair: Modern Chair
Table: Antique Table, Chair: Antique Chair

 


 

๐Ÿ”ฒ ์ถ”์ƒ ํŒฉํ† ๋ฆฌ์—์„œ ๋“ค์–ด์˜ค๋Š” ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ์˜ ํƒ€์ž…์— ๋”ฐ๋ผ ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

 

๐Ÿ”ฒ ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ด์œผ๋กœ์จ, ๊ฐ ์ œํ’ˆ๊ตฐ์— ์ผ์น˜ํ•˜๋Š” ์ œํ’ˆ(๊ตฌํ˜„์ฒด)๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”ฒ ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ์—์„œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” ํƒ€์ž…์€ ๊ฐ ์ œํ’ˆ์˜ ์ถ”์ƒ ์ œํ’ˆ(Abstract Product)์ด๋‹ค.

 

 


Structural Design Patterns(๊ตฌ์กฐ ํŒจํ„ด)

 

 

๊ตฌ์กฐ ํŒจํ„ด์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด๋ฅผ ๋”์šฑ ํฐ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค. ๊ตฌ์กฐ ํŒจํ„ด์˜ ์ข…๋ฅ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

  • Adapter
  • Bridge
  • Composite
  • Decorate
  • Facade
  • Flyweight
  • Proxy
  • ...

 

 

 

Adapter Patterns(์–ด๋Œ‘ํ„ฐ ํŒจํ„ด)

 

 

์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•ด ๋ณด์ž๋ฉด, ์ „์ž๊ธฐ๊ธฐ ๋‹จ์ž๋ฅผ ํ˜ธํ™˜ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์ฆ‰, ์–ด๋Œ‘ํ„ฐ๋Š” ํ•ด์™ธ์—ฌํ–‰์„ ๊ฐˆ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ฝ˜์„ผํŠธ์™€ ๋‚˜์˜ ์ „์ž๊ธฐ๊ธฐ๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์—ญํ• ๊ณผ ๋™์ผ ๋งฅ๋ฝ์ด๋‹ค.

 

๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„์  ๊ด€์ ์œผ๋กœ ์ด๋ฅผ ๋‹ค์‹œ ํ•ด์„ํ•˜์ž๋ฉด, ํ˜ธํ™˜์„ฑ ์—†๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๋•Œ๋ฌธ์— ๋™์ž‘ํ•˜์ง€ ๋ชปํ•˜๋Š” ํด๋ž˜์Šค๋“ค์„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค‘๊ฐ„์— ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ํŒจํ„ด์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์€ ์ƒ์†์„ ํ•˜๋ƒ, ํ•ฉ์„ฑ์„ ํ•˜๋ƒ์— ๋”ฐ๋ผ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‚˜๋‰œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ์ถ”์ฒœ๋˜๋Š” ๋ฐฉ๋ฒ•์ธ ๊ฐ์ฒด ์–ด๋Œ‘ํ„ฐ(Object Adapter)์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค.

 

์ƒ์†์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค ์–ด๋Œ‘ํ„ฐ์˜ ๊ฒฝ์šฐ, C++ ๊ฐ™์ด ๋‹ค์ค‘ ์ƒ์†์„ ์ง€์›ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

 

 

 

Object Adapter Pattern

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/adapter

 

 

๊ฐ์ฒด ์–ด๋Œ‘ํ„ฐ(Object Adapter)์˜ ํฐ ํŠน์ง•์œผ๋กœ๋Š” ๊ฐ์ฒด ํ•ฉ์„ฑ์˜ ์›์น™์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ํ•ฉ์„ฑ์„ ํ†ตํ•ด์„œ Client๋Š” Adapter๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” Service๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ Service๋Š” Adaptee๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๋Š”๋ฐ, ์ด ๊ฐ์ฒด๊ฐ€ Adapter์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ์จ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐ„ ์ฐจ์ง€ ๋น„์šฉ์ด ์กฐ๊ธˆ ๋” ๋“ ๋‹ค.

 

 

๐Ÿ”ฒ Service(Adaptee) : ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ์™ธ๋ถ€ ์‹œ์Šคํ…œ, ์จ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

๐Ÿ”ฒ Client Interface : Adapter๊ฐ€ ๊ตฌํ˜„ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค

 

๐Ÿ”ฒ Adapter : Client์™€ Service ์‚ฌ์ด๋ฅผ ์ด์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • Adaptee๋ฅผ ํด๋ž˜์Šค ๋ฉค๋ฒ„๋กœ ์„ค์ •ํ•œ ํ›„์—, ์œ„์ž„์„ ํ†ตํ•ด์„œ ๋™์ž‘ํ•˜๊ฒŒ ํ•œ๋‹ค.

๐Ÿ”ฒ Client : Client Interface๋ฅผ ํ†ตํ•ด Service๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

Object Adapter Pattern์„ C++๋กœ

 

#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>

class Json {};
class Xml {};
class Yaml {};

class Result {
  // Result ํด๋ž˜์Šค์˜ ์ •์˜
  // ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ ๋ฐ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ
};

class JsonAnalyzer {
  public:
  Result Analyze(Json json)  { /* JSON ๋ถ„์„ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ */ }
};

class XmlAnalyzer {
  public:
  XmlAnalyzer() : json_analyzer_() {}

  Result Analyze(Xml xml) {
    return json_analyzer_.Analyze(ToJson(xml));
  }

  private:
  Json ToJson(Xml xml) { /* XML์„ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ */ }
  JsonAnalyzer json_analyzer_;
};

class YamlAnalyzer {
  public:
  YamlAnalyzer() : json_analyzer_() {}

  Result Analyze(Yaml yaml) {
    return json_analyzer_.Analyze(ToJson(yaml));
  }

  private:
  Json ToJson(Yaml yaml) { /* YAML์„ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ */ }
  JsonAnalyzer json_analyzer_;
};

Xml GetXmlFile() { /* XML ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ */ }
Yaml GetYamlFile() { /* YAML ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ */ }

int main() {
  Xml xml = GetXmlFile();
  Yaml yaml = GetYamlFile();

  XmlAnalyzer xml_analyzer;
  YamlAnalyzer yaml_analyzer;

  Result xml_analysis_result = xml_analyzer.Analyze(xml);
  Result yaml_analysis_result = yaml_analyzer.Analyze(yaml);
  
  // ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ
}

 

๊ตฌ์ฒด์ ์ธ ๋กœ์ง์„ ์ƒ๋žตํ•˜๊ณ , ์–ด๋–ค ๊ตฌ์กฐ๋กœ ํŒจํ„ด์ด ๋™์ž‘ํ•˜๋Š” ์ง€ ์‚ดํŽด๋ณด์ž.

 

๐Ÿ”ฒ Adaptee(Service) : JsonAnalyzer๋กœ, json ํŒŒ์ผ๋งŒ์„ ๋ฐ›์•„ Result ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ์„œ๋น„์Šค์ด๋‹ค.

 

๐Ÿ”ฒ Adaptor : XmlAnalyzer, YamlAnalyzer๋กœ, xml๊ณผ yaml ํŒŒ์ผ์„ ๋ฐ›์•„ json์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋ฉฐ Adaptee(JsonAnlyzer)๋ฅผ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

 

๐Ÿ”ฒ Adaptee๋ฅผ ํ•ฉ์„ฑํ•˜๋Š” ๋ถ€๋ถ„์€ private์ด๋ฉฐ, ๋‚˜๋จธ์ง€ ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋ถ€๋ถ„์€ public์ด๋‹ค.

 

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/adapter

 

 


 

 

Bridge Patterns(๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด)

 

๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์€ ๊ฐ์ฒด์˜ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ํŒจํ„ด์œผ๋กœ, ๊ฐ์ฒด์— ๋„ˆ๋ฌด ๋งŽ์€ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋ฅผ ์œ„ํ•ด ๋ธŒ๋ฆฌ์ง€๋Š” ์ƒ์† ๋Œ€์‹  ๊ฐ์ฒด ํ•ฉ์„ฑ์ด๋ผ๋Š” ์ˆ˜๋‹จ์„ ํƒํ•œ๋‹ค. ์ƒ์†์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๊ธฐํ•˜ ๊ธ‰์ˆ˜์ ์ธ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ํ˜•์„ฑ๋  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

Adapter์—์„œ๋„ Service์— ๋Œ€ํ•œ ํ•ฉ์„ฑ์„ ํ†ตํ•ด ํ˜ธํ™˜์„ฑ์„ ๋งž์ถฐ์คฌ๋“ฏ์ด, ๋ธŒ๋ฆฌ์ง€๋„ ๊ฐ์ฒด ํ•ฉ์„ฑ์„ ํ†ตํ•ด ๊ธฐ๋Šฅ์˜ ํ–ฅ์ƒ์„ ๋„๋ชจํ•œ๋‹ค.

 

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/bridge

 

 

 

๊ทธ๋ฆผ์„ ๋ณด๋ฉด์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ๋ชจ์–‘์ด๋ผ๋Š” ํด๋ž˜์Šค ์•ˆ์— ์ƒ‰์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ํฌํ•จ ์‹œํ‚ด์œผ๋กœ์จ ํ™•์žฅ์— ๋”์šฑ ์œ ๋ฆฌํ•ด์กŒ๋‹ค.

 


 

๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

 

๐Ÿ”ฒ ๋ถ€๋ชจ ์ถ”์ƒ ํด๋ž˜์Šค(๋ชจ์–‘)์—์„œ ๊ธฐ๋ณธ์ ์ธ ๊ทœ์น™์ด ์ •์˜๋˜์–ด ์žˆ๊ณ , ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค(๋นจ๊ฐ•, ํŒŒ๋ž‘)๊ฐ€ ์ถ”๊ฐ€ ๊ทœ์น™์„ ์„ค์ •ํ•˜๊ณ  ์‹ถ์„ ๋•Œ

 

๐Ÿ”ฒ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๊ฐ€ ์žˆ๊ณ (๋ชจ์–‘), ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์—์„œ ์ •์˜๋  ์ถ”์ƒ ๋ฉ”์„œ๋“œ(์ƒ‰)๊ฐ€ ์กด์žฌํ•  ๋•Œ

 


 

 

์ถ”์ƒํ™”์™€ ๊ตฌํ˜„

 

๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์€ ์ถ”์ƒํ™”์™€ ๊ตฌํ˜„์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์„œ ๋งํ–ˆ๋“ฏ์ด, ๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์€ ๊ฐ์ฒด ํ•ฉ์„ฑ์„ ํ†ตํ•ด์„œ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ํ–ˆ๋‹ค. ์ฆ‰, ๊ฐ์ฒด ํ•ฉ์„ฑ์ด ์ด๋ฃจ์–ด์ง€๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๊ฐ€ ๋ฐ”๋กœ ์ถ”์ƒํ™”, ๊ทธ๋ฆฌ๊ณ  ํ•ฉ์„ฑ ๋‹นํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

 

ํ•˜์ง€๋งŒ, ์ถ”์ƒํ™” ๋ถ€๋ถ„๊ณผ ๊ตฌํ˜„ ๋ถ€๋ถ„์„ ๋‚˜๋ˆ„๊ณ  ๋ธŒ๋ฆฌ์ง€๋กœ ์ด์–ด์ค€๋‹ค๋ฉด, ๊ตณ์ด ์ „์ฒด ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์—†์–ด๋„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ ๋ฆฌํ•  ๊ฒƒ์ด๋‹ค.

 

 

 

 

Bridge Patterns(๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด)์˜ ๊ตฌ์กฐ

 

 

์ถœ์ฒ˜ : https://refactoring.guru/ko/design-patterns/bridge

 

 

 

 

๐Ÿ”ฒ Abstraction(์ถ”์ƒํ™”) : Remote์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์œผ๋กœ, Client๋Š” ์ถ”์ƒํ™”๋ฅผ ํ†ตํ•ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • private ๋ฉค๋ฒ„๋กœ ๊ตฌํ˜„ ๋ถ€๋ถ„์ธ Implementation ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•œ๋‹ค.(๊ฐ์ฒด ํ•ฉ์„ฑ)

 

๐Ÿ”ฒ Implementiation(๊ตฌํ˜„) : ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

 

๐Ÿ”ฒ Concrete Impementations(๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค) : ํ”Œ๋žซํผ ๋ณ„ ๋งž์ถค ์ฝ”๋“œ๊ฐ€ ์ œ๊ณต๋œ๋‹ค.

 

๐Ÿ”ฒ Refined Abstraction(์ •์ œํ™”๋œ ์ถ”์ƒํ™”) : ์ถ”์ƒํ™”์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ตฌํ˜„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์ž‘์—…ํ•œ๋‹ค

 

 

 

Bridge Patterns(๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด)์„ C++๋กœ

 

 

 

#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>

class Implementation {
 public:
  virtual ~Implementation() {}
  virtual std::string OperationImplementation() const = 0;
};

class ConcreteImplementationA : public Implementation {
 public:
  std::string OperationImplementation() const override {
    return "ConcreteImplementationA: Here's the result on the platform A.\n";
  }
};

class ConcreteImplementationB : public Implementation {
 public:
  std::string OperationImplementation() const override {
    return "ConcreteImplementationB: Here's the result on the platform B.\n";
  }
};

class Abstraction {

 protected:
  Implementation* implementation_;

 public:
  Abstraction(Implementation* implementation) : implementation_(implementation) {
  }

  virtual ~Abstraction() {
  }

  virtual std::string Operation() const {
    return "Abstraction: Base operation with:\n" +
           this->implementation_->OperationImplementation();
  }
};

class ExtendedAbstraction : public Abstraction {
 public:
  ExtendedAbstraction(Implementation* implementation) : Abstraction(implementation) {
  }
  std::string Operation() const override {
    return "ExtendedAbstraction: Extended operation with:\n" +
           this->implementation_->OperationImplementation();
  }
};


void ClientCode(const Abstraction& abstraction) {
  // ...
  std::cout << abstraction.Operation();
  // ...
}

int main() {
  Implementation* implementation = new ConcreteImplementationA;
  Abstraction* abstraction = new Abstraction(implementation);
  ClientCode(*abstraction);
  std::cout << std::endl;
  delete implementation;
  delete abstraction;

  implementation = new ConcreteImplementationB;
  abstraction = new ExtendedAbstraction(implementation);
  ClientCode(*abstraction);

  delete implementation;
  delete abstraction;

  return 0;
}

 

๐Ÿ”ฒ Client๋Š” Abstraction(์ถ”์ƒํ™”)์„ ํ†ตํ•ด์„œ ์‹ค์ œ ๊ตฌํ˜„ ๊ฐ์ฒด๋“ค๊ณผ ์†Œํ†ตํ•œ๋‹ค.

 

๐Ÿ”ฒ Abstraction์€ private ๋ฉค๋ฒ„๋กœ Implementation(๊ตฌํ˜„ ์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ๊ฐ€์ง„๋‹ค.

 

๐Ÿ”ฒ ExtendedAbstraction์€ Abstraction์˜ ์ƒ์†์„ ๋ฐ›์€ ํด๋ž˜์Šค๋กœ Abstraction๊ณผ ๋™์ผํ•˜๊ฒŒ Implementation์„ ํ†ตํ•ด ์†Œํ†ตํ•œ๋‹ค.

 

 

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ

Abstraction: Base operation with:
ConcreteImplementationA: Here's the result on the platform A.

ExtendedAbstraction: Extended operation with:
ConcreteImplementationB: Here's the result on the platform B.

 

 

 

 

 

Composite Pattern(๋ณตํ•ฉ์ฒด ํŒจํ„ด)

 

๋ณตํ•ฉ์ฒด ํŒจํ„ด(Composite Pattern)์€ ๋ณตํ•ฉ ๊ฐ์ฒด(Composite)์™€ ๋‹จ์ผ ๊ฐ์ฒด(Leaf)๋ฅผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ์ทจ๊ธ‰ํ•˜๊ณ , ๋‹จ์ผ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋Š” ๊ตฌ์กฐ ํŒจํ„ด์ด๋‹ค.

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/composite

 

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„์™€ ๊ฐ™์ด ๋ณต์žกํ•œ ์ฃผ๋ฌธ์ด ๋“ค์–ด ์™”๋‹ค๊ณ  ํ•˜์ž. ์ด ๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์ผ์ผ์ด ์ œํ’ˆ ํ•˜๋‚˜ํ•˜๋‚˜ ๋งˆ๋‹ค ๋”ํ•˜๊ธฐ๋ฅผ ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๋„ˆ๋ฌด๋‚˜๋„ ๋น„ํšจ์œจ์ ์ด๋‹ค.

 

๋”ฐ๋ผ์„œ ๋ณตํ•ฉ์ฒด ํŒจํ„ด์€ ์žฌ๊ท€์ ์œผ๋กœ ์—…๋ฌด๋ฅผ ์œ„์ž„ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•œ๋‹ค. ์ด๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ DFS์™€ ๊ต‰์žฅํžˆ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. DFS๋„ ๊ฒฐ๊ตญ ์žฌ๊ท€์ ์œผ๋กœ ํŒŒ๊ณ ๋“ค์–ด ์ผ๋ จ์˜ ์—…๋ฌด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํƒ์ƒ‰ ๊ธฐ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๋ณตํ•ฉ์ฒด ํŒจํ„ด์€ ์ด๊ฐ€๊ฒฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ์ œํ’ˆ๋“ค๊ณผ ์ƒ์ž๋“ค์—๊ฒŒ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/composite

 

 

 

 

 

Composite Pattern(๋ณตํ•ฉ์ฒด ํŒจํ„ด)์˜ ๊ตฌ์กฐ

 

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/composite

 

 

 

๐Ÿ”ฒ Component : Leaf์™€ Composite๋ฅผ ๋ฌถ๋Š” ๊ณตํ†ต ์ƒ์œ„ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.

 

๐Ÿ”ฒ Composite : ๋ณตํ•ฉ ๊ฐ์ฒด๋กœ, Leaf๋‚˜ Composite๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • ๋ณด๊ด€์€ ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ†ตํ•ด์„œ ๊ด€๋ฆฌํ•œ๋‹ค.
  • add์™€ remove ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ์— ๋‹จ์ผ/๋ณตํ•ฉ ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ญ์ œํ•œ๋‹ค.
  • excute()๋ฅผ ํ†ตํ•ด์„œ ํ•˜์œ„ ๋ณตํ•ฉ ๊ฐ์ฒด๋ฅผ ์ˆœํ™˜ํ•œ๋‹ค.

๐Ÿ”ฒ Leaf : ๋‹จ์ผ ๊ฐ์ฒด์ด๋‹ค. excute()๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด, ๋‚ด์šฉ๋ฌผ๋งŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

๐Ÿ”ฒ Client : Component๋ฅผ ํ†ตํ•ด์„œ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

Composite Pattern(๋ณตํ•ฉ์ฒด ํŒจํ„ด)๋ฅผ C++๋กœ

 

Component

class Company {
  public:
  void Hire(Employee* employee) {
    employees_.push_back(employee);
  }
  std::string GetInfo() {
    std::string res = "";
    for(Employee* employee : employees_) {
      res += employee -> GetInfo() + "\n";
    }
    return res;
  }
  private:
  std::vector<Employee*> employees_;
};

 

๐Ÿ”ฒ GetInfo()๋Š” excute()๋กœ, ์žฌ๊ท€์ ์œผ๋กœ ์ด๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

๐Ÿ”ฒ Hire()๋Š” ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ๋กœ, ๋‹จ์ผ/๋ณตํ•ฉ ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค.

 

 

 

Leaf

class Employee {
  public:
  Employee(std::string name, int age, std::string dept) : name_(name),
  age_(age), dept_(dept) {}
  virtual std::string GetInfo() {
    return "Employee: " + name_ + "(" + std::to_string(age_) + ") @ " + dept_;
  }
  virtual ~Employee() {}

  protected:
  std::string name_;
  int age_;
  std::string dept_;
};

class Developer : public Employee {
  public:
  Developer(std::string name, int age, std::string dept) : Employee(name, age, dept) {}
  std::string GetInfo() {
    return "Developer: " + name_ + "(" + std::to_string(age_) + ") @ " + dept_;
  }
};

class Researcher : public Employee {
  public:
  Researcher(std::string name, int age, std::string dept) : Employee(name, age, dept) {}
  std::string GetInfo() {
    return "Researcher: " + name_ + "(" + std::to_string(age_) + ") @ " + dept_;
  }
};

class Leader : public Employee {
  public:
  Leader(std::string name, int age, std::string dept) : Employee(name, age, dept) {}
  std::string GetInfo() {
    return "Leader: " + name_ + "(" + std::to_string(age_) + ") @ " + dept_;
  }
};

 

 

 

๐Ÿ”ฒ ์ด ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ, Composite์˜ ์—ญํ• ์„ ํ•˜๋Š” ๋ถ€๋ถ„์€ Company ๋ฐ–์— ์—†๋‹ค. ์ฆ‰, Company๋Š” Composite์ด์ž, Component์ด๋‹ค.

 

๐Ÿ”ฒ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๋“ค์€ ์ „๋ถ€, Leaf ๋ถ€๋ถ„์œผ๋กœ GetInfo()๋ฅผ ํ†ตํ•ด ๊ทธ ๋‚ด์šฉ๋ฌผ ๋งŒ์„ ๋‚ด๋†“๋Š”๋‹ค. ์ด๋Š” virtual์„ ํ†ตํ•œ ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ๋‹ค.

 

 

 

 

Facade Pattern(ํผ์‚ฌ๋“œ ํŒจํ„ด)

 

 

ํผ์‚ฌ๋“œ(Facade) ํŒจํ„ด์€ ์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์™ธ๋ถ€ API๋ฅผ ๋‚ด ์ฝ”๋“œ์™€ ๊ฒฐํ•ฉํ•˜๊ณ ์ž ํ•  ๋•Œ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋„๋ก ํด๋ž˜์Šค๋ฅผ ์žฌ์ •๋ฆฌํ•˜๋Š” ๊ตฌ์กฐํŒจํ„ด์ด๋‹ค.

 

๋˜ํ•œ ํผ์‚ฌ๋“œ ํŒจํ„ด์€ ๋‹ค๋ฅธ ๋””์ž์ธ ํŒจํ„ด๊ณผ ๋‹ฌ๋ฆฌ ์ •ํ˜•ํ™”๋˜์–ด ์žˆ์ง€ ์•Š์€ ํŒจํ„ด์ด๋‹ค. ๊ทธ๋ž˜์„œ ํด๋ž˜์Šค๋“ค๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ํŠน๋ณ„ํžˆ ์ •ํ•ด์ ธ ์žˆ๊ฑฐ๋‚˜ ํ•˜์ง€๋Š” ์•Š๋‹ค. ๊ทธ์ € ํผ์‚ฌ๋“œ(Facade) ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด์„œ ๊ธฐ๋Šฅ์ด ์ง‘์•ฝํ™”๋˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ๋ณต์žกํ•œ ๊ฒƒ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ณด์—ฌ์ค€๋‹ค๋Š” ๊ฒƒ์ด ํผ์‚ฌ๋“œ ํŒจํ„ด์˜ ๋ชฉ์ ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

ํผ์‚ฌ๋“œ ํŒจํ„ด์˜ ํŠน์ง•

 

1๏ธโƒฃ ์‹œ์Šคํ…œ์ด ๋„ˆ๋ฌด ๋ณต์žกํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

2๏ธโƒฃ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋„ˆ๋ฌด ๋†’์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

3๏ธโƒฃ ๋ณต์žกํ•œ ์ฝ”๋“œ๋ฅผ ๊ฐ์ถ”๊ณ , Facade ํด๋ž˜์Šค๋งŒ์„ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4๏ธโƒฃ ์ฝ”๋“œ์˜ ์–‘์ด ๋งŽ์•„์ ธ, ์œ ์ง€๋ณด์ˆ˜ ๋ฉด์—์„œ ๋น„์šฉ์ด ๋” ๋“ ๋‹ค.

 

 


 

 

Facade Pattern(ํผ์‚ฌ๋“œ ํŒจํ„ด)์˜ ๊ตฌ์กฐ

 

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/facade

 

 

๐Ÿ”ฒ VideoConverter๋Š” Facade ํด๋ž˜์Šค๋กœ์จ, ๋ณต์žกํ•œ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์žฌ์ •๋ฆฌํ•˜์—ฌ ๋‚˜ํƒ€๋‚ธ๋‹ค.

 

๐Ÿ”ฒ Application์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์˜์กด ์—†์ด Facade๋ฅผ ํ†ตํ•ด์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

 

 

 

Facade Pattern(ํผ์‚ฌ๋“œ ํŒจํ„ด)์„ C++๋กœ

 

#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>

class Subsystem1 {
 public:
  std::string Operation1() const { return "Subsystem1: Ready!\n"; }
  // ...
  std::string OperationN() const { return "Subsystem1: Go!\n"; }
};

class Subsystem2 {
 public:
  std::string Operation1() const { return "Subsystem2: Get ready!\n"; }
  // ...
  std::string OperationZ() const { return "Subsystem2: Fire!\n"; }
};

class Facade {
 protected:
  Subsystem1 *subsystem1_;
  Subsystem2 *subsystem2_;

 public:
  Facade(Subsystem1 *subsystem1 = nullptr, Subsystem2 *subsystem2 = nullptr) {
    this->subsystem1_ = subsystem1 ?: new Subsystem1;
    this->subsystem2_ = subsystem2 ?: new Subsystem2;
  }
  ~Facade() {
    delete subsystem1_;
    delete subsystem2_;
  }

  std::string Operation() {
    std::string result = "Facade initializes subsystems:\n";
    result += this->subsystem1_->Operation1();
    result += this->subsystem2_->Operation1();
    result += "Facade orders subsystems to perform the action:\n";
    result += this->subsystem1_->OperationN();
    result += this->subsystem2_->OperationZ();
    return result;
  }
};

void ClientCode(Facade *facade) {
  // ...
  std::cout << facade->Operation();
  // ...
}

int main() {
  Subsystem1 *subsystem1 = new Subsystem1;
  Subsystem2 *subsystem2 = new Subsystem2;
  Facade *facade = new Facade(subsystem1, subsystem2);
  ClientCode(facade);

  delete facade;

  return 0;
}

 

๐Ÿ”ฒ Facade ํด๋ž˜์Šค๋Š” ๋‘ SubSystem(์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ž)์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ž‘์„ ๊ธฐ์ˆ ํ•œ๋‹ค.

 

๐Ÿ”ฒ Client๋Š” subsystem์„ Facade ๊ฐ์ฒด์— ๋“ฑ๋ก์‹œํ‚ค๊ณ , ์‹คํ–‰๋งŒ ํ•œ๋‹ค.(๋‚˜๋จธ์ง€ ์„ธ๋ถ€ ๋กœ์ง์€ Facade ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋œ๋‹ค.

 

 

Facade Pattern(ํผ์‚ฌ๋“œ ํŒจํ„ด)์„ Java์—์„œ

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋Š”๋ฐ ์บ์‹œ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž. ๊ทธ๋ ‡๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋กœ์ง์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐํšŒ๋œ๋‹ค.

 

์กฐํšŒํ•  ๋ฐ์ดํ„ฐ ์ •๋ณด ๋ณ€์ˆ˜ a;

if (๋ฐ์ดํ„ฐ๊ฐ€ ์บ์‹œ์— ์žˆ๋‹ค๋ฉด) {
    a = ์บ์‹œ์—์„œ ์กฐํšŒ ๋ฐ ๋ฐ˜ํ™˜;
} else {
    a = DB์—์„œ ๋ฐ์ดํ„ฐ ์กฐํšŒ ๋ฐ ๋ฐ˜ํ™˜;
    a๋ฅผ ์บ์‹œ์— ์ €์žฅ
}

a๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ์ถœ๋ ฅ

 

 

์ด ๊ณผ์ •์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํด๋ž˜์Šค๋Š” Cache ์กฐํšŒ, DBMS ์กฐํšŒ, Cache ์ž…๋ ฅ, ์กฐํšŒ ๊ฒฐ๊ณผ ๊ฐ€๊ณต, ๊ฐ€๊ณต ๊ฒฐ๊ณผ ์ถœ๋ ฅ์ด๋‹ค.

์ด์— ๋Œ€ํ•œ ํด๋ž˜์Šค๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒƒ์ด๋‹ค.

 

class Row  {
    private String name;
    private String birthday;
    private String email;

    public Row(String name, String birthday, String email) {
        this.name = name;
        this.birthday = birthday;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public String getBirthday() {
        return birthday;
    }

    public String getEmail() {
        return email;
    }
}

class DBMS {
    private HashMap<String, Row> db = new HashMap<>();

    public void put(String name, Row row) {
        db.put(name, row);
    }

    public Row query(String name) {
        try {
            Thread.sleep(500);
        } catch(InterruptedException e) {}

        return db.get(name.toLowerCase());
    }
}

class Cache {
    private HashMap<String, Row> cache = new HashMap<>();

    public void put(Row row) {
        cache.put(row.getName(), row);
    }

    public Row get(String name) {
        return cache.get(name);
    }
}

class Message {
    private Row row;

    public Message(Row row) {
        this.row = row;
    }

    public String makeName() {
        return "Name : \"" + row.getName() + "\"";
    }

    public String makeBirthday() {
        return "Birthday : " + row.getBirthday();
    }

    public String makeEmail() {
        return "Email : " + row.getEmail();
    }
}

 

์œ„ ํด๋ž˜์Šค ์ฝ”๋“œ๋ฅผ main ํ•จ์ˆ˜์— ํ•˜๋‚˜ํ•˜๋‚˜ ์ ์šฉํ•ด๋‚˜๊ฐ€๋ฉฐ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ์ด๋Š” ํด๋ฆฐํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ด๋‹ค. ์œ ์ง€ ๋ณด์ˆ˜ํ•˜๊ธฐ ํž˜๋“ค๋ฉฐ ์ฝ”๋“œ ๋กœ์ง์„ ํ•ด์„ํ•˜๊ธฐ๋„ ํž˜๋“ค์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ด์— ๋”ฐ๋ผ Facade ํด๋ž˜์Šค๋ฅผ ๋„์ž…ํ•˜์—ฌ "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋Š”๋ฐ ์บ์‹œ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๋Š”" ๋กœ์ง์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•œ๋‹ค๋ฉด ์œ ์ง€๋ณด์ˆ˜์™€ ์ฝ”๋“œ ํ•ด์„์— ์žˆ์–ด ๋งค์šฐ ์œ ๋ฆฌํ•ด ์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

 

class Client {
    public static void main(String[] args) {

        Facade facade = new Facade();
        facade.insert();

		// ์บ์‹œ ํ™œ์šฉ DB ์กฐํšŒ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” Facade์˜ run() ๋ฉ”์„œ๋“œ
        String name = "ํ™๊ธธ๋™";
        facade.run(name);
    }
}

 

 

 

 

Froxy Pattern(ํ”„๋ก์‹œ ํŒจํ„ด)

 

ํ”„๋ก์‹œ ํŒจํ„ด์€ ์ƒ๊ธด ๋ชจ์–‘์œผ๋กœ๋Š” ํผ์‚ฌ๋“œ ํŒจํ„ด๊ณผ ํฐ ์ฐจ์ด๊ฐ€ ์—†๋‹ค. ๋‹จ, dependency ๊ฐ์†Œ๊ฐ€ ๋ชฉ์ ์ด์—ˆ๋˜ Facade์™€๋Š” ๋‹ฌ๋ฆฌ Proxy๋Š” ์„ฑ๋Šฅ ํ–ฅ์ƒ ๋ฐ ์ธ๊ฐ€๊ฐ€ ์ฃผ ๋ชฉ์ ์ด๋‹ค.

 

 

์ฆ‰, ํ”„๋ก์‹œ ํŒจํ„ด์ด๋ž€ ์›๋ณธ ๊ฐ์ฒด ๋Œ€๋ฆฌ๋กœ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํŒจํ„ด์ธ๋ฐ, ์›๋ณธ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ํ”„๋ก์‹œ ํŒจํ„ด์œผ๋กœ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋Š” ํšจ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

1๏ธโƒฃ ๋ณด์•ˆ : ํ”„๋ก์‹œ์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๊ณ  ์›๋ณต ๊ฐ์ฒด๋กœ์˜ ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ง€ ํ™•์ธํ•˜๋Š” ์—ญํ• 

 

2๏ธโƒฃ ์บ์‹ฑ : ํ”„๋ก์‹œ๊ฐ€ ๋‚ด๋ถ€ ์บ์‹œ๋ฅผ ์œ ์ง€ํ•˜์—ฌ, ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์บ์‹œ๋ฅผ ์ด๋ฏธ ๋ณด์œ ํ•˜๊ณ  ์žˆ์„ ๋•Œ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ญํ• 

 

3๏ธโƒฃ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ : ์ž…๋ ฅ์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ธฐ๋Šฅ

 

4๏ธโƒฃ ์ง€์—ฐ ์ดˆ๊ธฐํ™” : ๋งŒ์•ฝ ๋Œ€์ƒ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑํ• ๋•Œ ๋น„์šฉ์ด ๋งŽ์ด ๋“ ๋‹ค๋ฉด, ํ•„์š”๋กœ ํ• ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ์‚ฌ์šฉ ์‹œ๊ธฐ์— ์ƒ์„ฑํ•˜๋Š” ์—ญํ• 

 

5๏ธโƒฃ ๋กœ๊น… : ์›๋ณธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ํ˜ธ์ถœ ์‹œ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ์—ญํ• 

 

6๏ธโƒฃ ์›๊ฒฉ ๊ฐ์ฒด : ํ”„๋ก์‹œ๊ฐ€ ์›๊ฒฉ์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋กœ์ปฌ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ํ•˜๋Š” ์—ญํ• 

 

 

 

 

Froxy Pattern(ํ”„๋ก์‹œ ํŒจํ„ด)์˜ ๊ตฌ์กฐ

 

์ถœ์ฒ˜ :&nbsp;https://refactoring.guru/ko/design-patterns/proxy

 

๐Ÿ”ฒ ์‚ฌ์šฉ์ž๋Š” ServiceInterface๋ฅผ ํ†ตํ•ด์„œ ๋Œ€์ƒ ๊ฐ์ฒด(Service)์— ๋Œ€ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”ฒ Proxy๋Š” ๋Œ€์ƒ ๊ฐ์ฒด(Service)๋ฅผ ํ•ฉ์„ฑํ•œ๋‹ค.

 

๐Ÿ”ฒ Service๋Š” ์›๋ณธ ๋Œ€์ƒ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

 

 

Froxy Pattern(ํ”„๋ก์‹œ ํŒจํ„ด)์„ C++๋กœ

 

๋ณด์•ˆ๊ณผ ์บ์‹ฑ์˜ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ํ”„๋ก์‹œ ํŒจํ„ด์„ ๊ฐ„๋‹จํ•˜๊ฒŒ C++๋กœ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ๋‹ค.

 

 

 

์ค€๋น„ํ•  ํด๋ž˜์Šค(์บ์‹ฑ ํด๋ž˜์Šค, Person, Result ํด๋ž˜์Šค)

class Result {
 public:
  Result() { /* ์ƒ์„ฑ์ž ๊ตฌํ˜„ */
  }
  // ๋‹ค๋ฅธ ๋ฉค๋ฒ„ ๋ฐ ๋™์ž‘์„ ์ถ”๊ฐ€๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
};

class Person {
 public:
  Person(std::string name) : name_(name) { }/* ์ƒ์„ฑ์ž ๊ตฌํ˜„ */
  std::string name() const {
    return name_;
  }
  
  private:
  std::string name_;
};

class Cache {
 public:
  Cache() { /* ์ƒ์„ฑ์ž ๊ตฌํ˜„ */
  }
  bool IsCached(std::string query) {
    // ์บ์‹œ ํ™•์ธ ๋กœ์ง ๊ตฌํ˜„
    return false;
  }

  Result GetCachedData(std::string query) {
    // ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜ ๋กœ์ง ๊ตฌํ˜„
    return Result();
  }

  void Update(std::string query, std::experimental::optional<Result> result) {
    std::cout << "update cache for person" << std::endl;
    // ์บ์‹œ ์—…๋ฐ์ดํŠธ ๋กœ์ง ๊ตฌํ˜„
  }
};

 

 

 

 

Service Interface, Service, Proxy

class QueryInterface {
public:
    virtual std::experimental::optional<Result> Query(Person accessor, std::string query) = 0;
};

class NetworkAdapter : public QueryInterface {
public:
    std::experimental::optional<Result> Query(Person accessor, std::string query) override {
        // ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง ๊ตฌํ˜„
        std::cout << "data fetch in NetworkAdapter." << std::endl;
        return Result();
    }
};

class NetworkProxy : public QueryInterface {
public:
    NetworkProxy(Person manager) : network_manager_(manager) {}
    std::experimental::optional<Result> Query(Person accessor, std::string query) override {
        // ๋“ค์–ด์˜จ ๊ฐ’์— ๋Œ€ํ•œ ์ธ๊ฐ€ ๊ณผ์ •
        if (network_manager_.name() == accessor.name()) {
            // ์บ์‰ฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ๋Œ€๋กœ ์คŒ
            if (cache_.IsCached(query)) {
                return cache_.GetCachedData(query);
            // ์บ์‰ฌ๊ฐ€ ์—†๋‹ค๋ฉด, network_adapter๋กœ ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜ด
            } else {
                std::experimental::optional<Result> result = network_adapter_.Query(accessor, query);  // Query ํ•จ์ˆ˜์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ๋ณ€๊ฒฝ
                cache_.Update(query, result);
                return result;
            }
        }
        // ์•„์˜ˆ ์—†์œผ๋ฉด null ๊ฐ’ ๋ฆฌํ„ด
        return std::experimental::nullopt;
    }

private:
    const Person network_manager_;
    Cache cache_;
    NetworkAdapter network_adapter_;
};

 

 

๐Ÿ”ฒ QueryInterface : Service Interface๋กœ ํ•˜์œ„ ์ž์‹์œผ๋กœ Proxy์™€ Service๋ฅผ ๋‘”๋‹ค.

 

๐Ÿ”ฒ NetworkAdapter : Service๋กœ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๋Š” ํด๋ž˜์Šค์ด๋‹ค.

 

๐Ÿ”ฒ NetworkProxy : ์บ์‹ฑ ๊ธฐ๋Šฅ๊ณผ ๋ณด์•ˆ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. NetworkAdapter๋ฅผ ํ•ฉ์„ฑํ•œ๋‹ค.

 

 

main ํ•จ์ˆ˜

int main() {
  Person manager("person1");               // Person ๊ฐ์ฒด ์ƒ์„ฑ
  NetworkProxy proxy(manager);  // NetworkProxy ๊ฐ์ฒด ์ƒ์„ฑ
  std::experimental::optional<Result> result1 =
      proxy.Query(manager, "find name from internet");
  std::experimental::optional<Result> result2 =
      proxy.Query(manager, "find name from internet");
}

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ

data fetch in NetworkAdapter.
update cache for person
data fetch in NetworkAdapter.
update cache for person

 

 

์ž๋ฐ”์—์„œ๋„ Dynamic Proxy, Spring Framework์—์„œ๋Š” Spring AOP ๋“ฑ Proxy๋Š” ์ •๋ง ๋งŽ์€ ๊ณณ์—์„œ ์“ฐ์ด๊ณ  ์žˆ๋‹ค. ์ด์™€ ๊ด€๋ จ๋œ ๋ถ€๋ถ„์€ ํ›„์— ํฌ์ŠคํŒ… ์˜ˆ์ •์ด๋‹ค.

 

 

 

 

 

References

 

 

๋””์ž์ธ ํŒจํ„ด๋“ค

 

refactoring.guru

 

[Java][๋””์ž์ธ ํŒจํ„ด] 8. ๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด (Bridge Pattern)

๋””์ž์ธํŒจํ„ด [Java][๋””์ž์ธ ํŒจํ„ด] 8. ๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด ๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์€ ๊ฐ์ฒด์˜ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•œ ํŒจํ„ด์œผ๋กœ, ๊ฐ์ฒด์—์„œ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ตฌํ˜„๋ถ€์™€ ํ™•์žฅ์„ ์œ„ํ•œ ์ถ”์ƒ๋ถ€๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค. ๋ธŒ๋ฆฌ์ง€ ํŒจํ„ด์ด๋ž€?

hirlawldo.tistory.com

 

 

๐Ÿ’  ๋ณตํ•ฉ์ฒด(Composite) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

Composite Pattern ๋ณตํ•ฉ์ฒด ํŒจํ„ด(Composite Pattern)์€ ๋ณตํ•ฉ ๊ฐ์ฒด(Composite) ์™€ ๋‹จ์ผ ๊ฐ์ฒด(Leaf)๋ฅผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ด ๋‘˜์„ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋Š”

inpa.tistory.com

 

์ฝ”๋”ฉ์œผ๋กœ ํ•™์Šตํ•˜๋Š” GoF์˜ ๋””์ž์ธ ํŒจํ„ด - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

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

www.inflearn.com

 

 

๐Ÿ’  ํผ์‚ฌ๋“œ(Facade) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

Facade Pattern ํผ์‚ฌ๋“œ ํŒจํ„ด(Facade Pattern)์€ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณต์žกํ•œ ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ๊ฐ„ํŽธํ•œ ์ธํ„ฐํŽ˜์ด์Šค(API)๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์กฐ ํŒจํ„ด ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐ ํด๋ž˜์Šค

inpa.tistory.com

 

๐Ÿ’  ์–ด๋Œ‘ํ„ฐ(Adaptor) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

Adaptor Pattern ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด(Adaptor Pattern) ์ด๋ž€ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ํด๋ž˜์Šค๋ฅผ ์–ด๋Œ‘ํ„ฐ๋กœ์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์กฐ ํŒจํ„ด์ด๋‹ค. ์–ด๋Œ‘ํ„ฐ๋Š” ์šฐ๋ฆฌ ์ฃผ๋ณ€์—๋„ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ์„œ, ๋Œ€ํ‘œ์ ์œผ๋กœ 110V ์ „์šฉ ๊ฐ€์ „์ œํ’ˆ์— 220V

inpa.tistory.com

 

๐Ÿ’  ํ”„๋ก์‹œ(Proxy) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

Proxy Pattern ํ”„๋ก์‹œ ํŒจํ„ด(Proxy Pattern)์€ ๋Œ€์ƒ ์›๋ณธ ๊ฐ์ฒด๋ฅผ ๋Œ€๋ฆฌํ•˜์—ฌ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ๋กœ์ง์˜ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ํ–‰๋™ ํŒจํ„ด์ด๋‹ค. ํ”„๋ก์‹œ(Proxy)์˜ ์‚ฌ์ „์ ์ธ ์˜๋ฏธ๋Š” '๋Œ€๋ฆฌ์ธ'์ด๋ผ๋Š” ๋œป์ด๋‹ค. ์ฆ‰, ๋ˆ„

inpa.tistory.com

 

 

๐Ÿ’  ์ถ”์ƒ ํŒฉํ† ๋ฆฌ(Abstract Factory) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

Abstract Factory Pattern ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์€ ์—ฐ๊ด€์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด ๊ตฐ์ด ์—ฌ๋Ÿฌ๊ฐœ ์žˆ์„ ๊ฒฝ์šฐ ์ด๋“ค์„ ๋ฌถ์–ด ์ถ”์ƒํ™”ํ•˜๊ณ , ์–ด๋–ค ๊ตฌ์ฒด์ ์ธ ์ƒํ™ฉ์ด ์ฃผ์–ด์ง€๋ฉด ํŒฉํ† ๋ฆฌ ๊ฐ์ฒด์—์„œ ์ง‘ํ•ฉ์œผ๋กœ ๋ฌถ์€ ๊ฐ์ฒด ๊ตฐ์„ ๊ตฌํ˜„ํ™”

inpa.tistory.com