λ””μžμΈνŒ¨ν„΄

[λ””μžμΈνŒ¨ν„΄] μ „λž΅(Strategy) νŒ¨ν„΄

μ„œμ•„λž‘πŸ˜ 2024. 8. 24. 08:29

 

μ „λž΅(Strategy) νŒ¨ν„΄

  • μ „λž΅ νŒ¨ν„΄(Strategy Pattern)은 객체의 행동 방식을 μΊ‘μŠν™”ν•˜μ—¬ λ™μ μœΌλ‘œ ꡐ체할 수 μžˆλ„λ‘ ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€. 이 νŒ¨ν„΄μ€ 객체의 ν–‰μœ„(behavior)λ₯Ό 클래슀둜 λΆ„λ¦¬ν•˜κ³ , λŸ°νƒ€μž„μ— κ·Έ 행동을 μ„ νƒν•˜κ±°λ‚˜ λ³€κ²½ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ μœ μ—°μ„±κ³Ό ν™•μž₯성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

1. μ „λž΅ νŒ¨ν„΄μ˜ κΈ°λ³Έ κ°œλ…

ꡬ성 μš”μ†Œ:

  • Context: νŠΉμ • μ „λž΅μ„ μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ ν΄λž˜μŠ€μž…λ‹ˆλ‹€. 이 ν΄λž˜μŠ€λŠ” Strategy 객체λ₯Ό 가지고 있으며, ν•„μš”μ— 따라 이λ₯Ό λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Strategy: μ „λž΅μ˜ 곡톡 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. 이 μΈν„°νŽ˜μ΄μŠ€λŠ” νŠΉμ • μž‘μ—…(행동)에 λŒ€ν•΄ κ³΅ν†΅λœ λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•©λ‹ˆλ‹€.
  • Concrete Strategy: Strategy μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” ꡬ체적인 μ „λž΅ ν΄λž˜μŠ€μž…λ‹ˆλ‹€. 각 ν΄λž˜μŠ€λŠ” νŠΉμ •ν•œ μ•Œκ³ λ¦¬μ¦˜μ΄λ‚˜ 행동을 κ΅¬ν˜„ν•©λ‹ˆλ‹€.



μž₯점:

  • μ•Œκ³ λ¦¬μ¦˜μ„ λ…λ¦½μ μœΌλ‘œ λΆ„λ¦¬ν•˜μ—¬ μ½”λ“œ μž¬μ‚¬μš©μ„±μ„ 높이고, μ½”λ“œμ˜ 가독성을 κ°œμ„ ν•©λ‹ˆλ‹€.
  • λŸ°νƒ€μž„μ— μ „λž΅μ„ λ³€κ²½ν•  수 μžˆμ–΄ 동적인 λ™μž‘ 변경이 κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • μƒˆλ‘œμš΄ μ „λž΅μ„ μΆ”κ°€ν•˜λ”λΌλ„ κΈ°μ‘΄ μ½”λ“œλ₯Ό μˆ˜μ •ν•  ν•„μš”κ°€ μ—†μœΌλ―€λ‘œ 개방-폐쇄 원칙(Open-Closed Principle)을 μ€€μˆ˜ν•©λ‹ˆλ‹€.

단점:

  • μ „λž΅ ν΄λž˜μŠ€κ°€ λ§Žμ•„μ§ˆ 경우 관리가 λ³΅μž‘ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈκ°€ μ μ ˆν•œ μ „λž΅μ„ μ„ νƒν•˜λŠ” 둜직이 μΆ”κ°€λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.



2. μ „λž΅ νŒ¨ν„΄ 예제

μ•„λž˜ μ˜ˆμ œμ—μ„œλŠ” κ°„λ‹¨ν•œ ν…μŠ€νŠΈ μ •λ ¬ ν”„λ‘œκ·Έλž¨μ—μ„œ μ „λž΅ νŒ¨ν„΄μ„ μ μš©ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€. ν…μŠ€νŠΈλ₯Ό 쒌츑 μ •λ ¬, 우츑 μ •λ ¬, 쀑앙 μ •λ ¬ν•˜λŠ” μ—¬λŸ¬ 가지 μ „λž΅μ„ κ΅¬ν˜„ν•˜κ³ , ν•„μš”μ— 따라 λŸ°νƒ€μž„μ— μ •λ ¬ 방식을 λ³€κ²½ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

#include <iostream>
#include <memory>
#include <string>

// Strategy
class TextAlignmentStrategy {
public:
    virtual void align(const std::string& text) const = 0;
    virtual ~TextAlignmentStrategy() = default;
};

// Concrete Strategy - Left Alignment
class LeftAlignStrategy : public TextAlignmentStrategy {
public:
    void align(const std::string& text) const override {
        std::cout << text << std::endl;
    }
};

// Concrete Strategy - Right Alignment
class RightAlignStrategy : public TextAlignmentStrategy {
public:
    void align(const std::string& text) const override {
        std::cout << std::string(50 - text.length(), ' ') << text << std::endl;
    }
};

// Concrete Strategy - Center Alignment
class CenterAlignStrategy : public TextAlignmentStrategy {
public:
    void align(const std::string& text) const override {
        int padding = (50 - text.length()) / 2;
        std::cout << std::string(padding, ' ') << text << std::endl;
    }
};

// Context
class TextEditor {
private:
    std::unique_ptr<TextAlignmentStrategy> alignmentStrategy;

public:
    TextEditor(std::unique_ptr<TextAlignmentStrategy> strategy)
        : alignmentStrategy(std::move(strategy)) {}

    void setAlignmentStrategy(std::unique_ptr<TextAlignmentStrategy> strategy) {
        alignmentStrategy = std::move(strategy);
    }

    void render(const std::string& text) const {
        alignmentStrategy->align(text);
    }
};

int main() {
    // 기본적으둜 μ™Όμͺ½ 정렬을 μ‚¬μš©
    TextEditor editor(std::make_unique<LeftAlignStrategy>());
    editor.render("Hello, Strategy Pattern!");

    // 였λ₯Έμͺ½ μ •λ ¬λ‘œ λ³€κ²½
    editor.setAlignmentStrategy(std::make_unique<RightAlignStrategy>());
    editor.render("Hello, Strategy Pattern!");

    // 쀑앙 μ •λ ¬λ‘œ λ³€κ²½
    editor.setAlignmentStrategy(std::make_unique<CenterAlignStrategy>());
    editor.render("Hello, Strategy Pattern!");

    return 0;
}

3. μ½”λ“œ μ„€λͺ…

  1. Strategy: TextAlignmentStrategyλŠ” ν…μŠ€νŠΈ 정렬을 μœ„ν•œ μ „λž΅μ˜ μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. align() λ©”μ„œλ“œλŠ” ν…μŠ€νŠΈλ₯Ό μ •λ ¬ν•˜λŠ” λ™μž‘μ„ μ •μ˜ν•©λ‹ˆλ‹€.
  2. Concrete Strategy:
    • LeftAlignStrategy: ν…μŠ€νŠΈλ₯Ό μ™Όμͺ½μ— μ •λ ¬ν•©λ‹ˆλ‹€.
    • RightAlignStrategy: ν…μŠ€νŠΈλ₯Ό 였λ₯Έμͺ½μ— μ •λ ¬ν•©λ‹ˆλ‹€.
    • CenterAlignStrategy: ν…μŠ€νŠΈλ₯Ό 쀑앙에 μ •λ ¬ν•©λ‹ˆλ‹€.
  3. Context: TextEditor ν΄λž˜μŠ€λŠ” ν˜„μž¬μ˜ μ •λ ¬ μ „λž΅μ„ μœ μ§€ν•˜λ©°, render() λ©”μ„œλ“œλ₯Ό 톡해 ν…μŠ€νŠΈλ₯Ό 좜λ ₯ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€. 이 ν΄λž˜μŠ€λŠ” setAlignmentStrategy() λ©”μ„œλ“œλ₯Ό 톡해 λ™μ μœΌλ‘œ μ •λ ¬ 방식을 λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

4. μ‹€ν–‰ κ²°κ³Ό

μœ„μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ λ‹€μŒκ³Ό 같은 좜λ ₯이 λ‚˜νƒ€λ‚©λ‹ˆλ‹€:

Hello, Strategy Pattern!
                             Hello, Strategy Pattern!
             Hello, Strategy Pattern!
  1. μ²˜μŒμ—λŠ” LeftAlignStrategyλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…μŠ€νŠΈκ°€ μ™Όμͺ½μ— μ •λ ¬λ©λ‹ˆλ‹€.
  2. 두 번째둜 RightAlignStrategyλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…μŠ€νŠΈκ°€ 였λ₯Έμͺ½μ— μ •λ ¬λ©λ‹ˆλ‹€.
  3. λ§ˆμ§€λ§‰μœΌλ‘œ CenterAlignStrategyλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…μŠ€νŠΈκ°€ 쀑앙에 μ •λ ¬λ©λ‹ˆλ‹€.

이 μ˜ˆμ œλŠ” μ „λž΅ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ—¬ ν…μŠ€νŠΈ μ •λ ¬ 방법을 λ™μ μœΌλ‘œ λ³€κ²½ν•˜λŠ” 방법을 λ³΄μ—¬μ€λ‹ˆλ‹€. μ „λž΅ νŒ¨ν„΄μ„ μ‚¬μš©ν•¨μœΌλ‘œμ¨ λ‹€μ–‘ν•œ μ •λ ¬ 방법을 μ‰½κ²Œ κ΅μ²΄ν•˜κ³  ν™•μž₯ν•  수 있게 λ©λ‹ˆλ‹€.