Strategy Design Pattern

์ •ํ˜œ์ฐฝยท2025๋…„ 2์›” 25์ผ
0

๋‚ด์ผ๋ฐฐ์›€์บ ํ”„

๋ชฉ๋ก ๋ณด๊ธฐ
33/43

๐ŸŽฎ ๊ฐœ๋…

์ „๋žต ํŒจํ„ด์€ ๊ฐ์ฒด์˜ ํ–‰์œ„๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œ, ์ง์ ‘ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ „๋žต ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ต์ฒดํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ธ๋‹ค. ์ด๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ๊ฐœ๋ฐฉ-ํ์‡„์›์น™ OCP์„ ๋”ฐ๋ฅด๋ฉฐ, ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.


๐ŸŽฎ ์˜ˆ์ œ

์ด๋ฒˆ ๊ณผ์ œ๋Š” ์ˆ˜์—… ์ค‘์— ์„ค๋ช…ํ–ˆ๋˜ ์˜ค๋ฆฌ, ์ƒ์  ์˜ˆ์ œ๋ฅผ C++ ์ „๋žต ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•˜์—ฌ ์ถœ๋ ฅ๊นŒ์ง€ ํ•ด๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

1๏ธโƒฃ ์˜ค๋ฆฌ

๐Ÿ“Œ ์ฝ”๋“œ

#include <iostream>
#include <memory>

class IFlyBehavior
{
public:
	virtual void Fly() = 0;
	virtual ~IFlyBehavior() = default;
};

class IQuackBehavior
{
public:
	virtual void Quack() = 0;
	virtual ~IQuackBehavior() = default;
};

// =====================================================

class FlyNoWay : public IFlyBehavior
{
public:
	virtual void Fly() override
	{
		std::cout << "๋‚ ๊ฐœ๋กœ ๋‚ฉ๋‹ˆ๋‹ค" << std::endl;
	}
};

class FlyRocketPowered : public IFlyBehavior
{
public:
	virtual void Fly() override
	{
		std::cout << "๋กœ์ผ“ ์ถ”์ง„์œผ๋กœ ์—„์ฒญ๋‚˜๊ฒŒ ๋‚ ์•„๊ฐ‘๋‹ˆ๋‹ค!" << std::endl;
	}
};

// =====================================================

class QuackQuack : public IQuackBehavior
{
public:
	virtual void Quack() override
	{
		std::cout << "๊ฝฅ๊ฝฅ ์†Œ๋ฆฌ๋ฅผ ๋ƒ…๋‹ˆ๋‹ค" << std::endl;
	}
};

class Squeak : public IQuackBehavior
{
public:
	virtual void Quack() override
	{
		std::cout << "์‚‘์‚‘ ์†Œ๋ฆฌ๋ฅผ ๋ƒ…๋‹ˆ๋‹ค" << std::endl;
	}
};

class MuteQuack : public IQuackBehavior
{
public:
	virtual void Quack() override
	{
		std::cout << "...(์นจ๋ฌต)" << std::endl;
	}
};

// =====================================================

class Duck
{
protected:
	std::unique_ptr<IFlyBehavior> flyBehavior;
	std::unique_ptr<IQuackBehavior> quackBehavior;

public:
	Duck(std::unique_ptr<IFlyBehavior> fly, std::unique_ptr<IQuackBehavior> quack) 
		: flyBehavior(std::move(fly)), quackBehavior(std::move(quack)) {};

	void Display()
	{
		PerformFly();
		PerformQuack();
		Swim();
	}

	void PerformFly()
	{
		if (flyBehavior)
		{
			flyBehavior->Fly();
		}
		else
		{
			std::cout << "์ด ์˜ค๋ฆฌ๋Š” ๋‚  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." << std::endl;
		}
	}

	void PerformQuack()
	{
		if (quackBehavior)
		{
			quackBehavior->Quack();
		}
		else
		{
			std::cout << "์ด ์˜ค๋ฆฌ๋Š” ์†Œ๋ฆฌ๋ฅผ ๋ชป ๋ƒ…๋‹ˆ๋‹ค." << std::endl;
		}
	}

	void Swim()
	{
		std::cout << "๋ชจ๋“  ์˜ค๋ฆฌ๋Š” ๋ฌผ์— ๋œน๋‹ˆ๋‹ค" << std::endl;
	}

	void SetFlyBehavior(std::unique_ptr<IFlyBehavior> fb)
	{
		flyBehavior = std::move(fb);
	}

	void SetQuackBehavior(std::unique_ptr<IQuackBehavior> qb)
	{
		quackBehavior = std::move(qb);
	}
};

// =====================================================

int main()
{
	Duck MallarDuck(std::make_unique<FlyNoWay>(), std::make_unique<QuackQuack>());
	std::cout << "=== ์ฒญ๋‘ฅ์˜ค๋ฆฌ ํŠน์ง• ===" << std::endl;
	MallarDuck.Display();

	MallarDuck.SetFlyBehavior(std::make_unique<FlyRocketPowered>());
	std::cout << "=== ๋ฐ”๋€ ์ฒญ๋‘ฅ์˜ค๋ฆฌ ===" << std::endl;
	MallarDuck.Display();
	
	Duck RubberDuck(nullptr, nullptr);
	std::cout << "=== ๊ณ ๋ฌด์˜ค๋ฆฌ ํŠน์ง• ===" << std::endl;
	RubberDuck.Display();

	RubberDuck.SetQuackBehavior(std::make_unique<MuteQuack>());
	std::cout << "=== ๋ฐ”๋€ ๊ณ ๋ฌด์˜ค๋ฆฌ ===" << std::endl;
	RubberDuck.Display();

	return 0;
}

๐Ÿ“Œ ์ถœ๋ ฅ๊ฒฐ๊ณผ

  • ์ƒ์„ฑ์ž๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์ง€ ์•Š๊ณ  ๋” ์‰ฝ๊ฒŒ ํ•˜๋ ค๋ฉด ๋”ฐ๋กœ Duck์„ ์ƒ์†๋ฐ›๋Š” MallarDuck, RubberDuck ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ•ด๋‹น ์ƒ์„ฑ์ž์˜ ๊ตฌํ˜„๋ถ€์— flyBehavior ์ด๋‚˜ quackBehavior์„ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค.

  • ๋งค๊ฐœ๋ณ€์ˆ˜์— nullptr์„ ๋Œ€๋น„ํ•ด์„œ Perform ๋ฉ”์†Œ๋“œ๋“ค์˜ ๊ตฌํ˜„๋ถ€์—์„œ ์กฐ๊ฑด๋ฌธ์„ ๋งŒ๋“ค์–ด๋‘์—ˆ๋‹ค.


2๏ธโƒฃ ํ• ์ธ

๐Ÿ“Œ ์ฝ”๋“œ

#include <iostream>
#include <memory>

class IDiscountStrategy
{
public:
	virtual double ApplyDiscount(double amount) = 0;
};

class FixedDiscountStrategy : public IDiscountStrategy
{
private:
	double discountAmount;

public:
	FixedDiscountStrategy(double amount) : discountAmount(amount) {}

	virtual double ApplyDiscount (double amount)override
	{
		return amount - discountAmount;
	}
};

class PercentageDiscountStrategy : public IDiscountStrategy
{
private:
	double percentage;

public:
	PercentageDiscountStrategy(double percent) : percentage(percent) {}

	virtual double ApplyDiscount(double amount)override
	{
		return amount * (1 - (percentage / 100));
	}
};

class NoDiscountStrategy : public IDiscountStrategy
{
public:
	virtual double ApplyDiscount(double amount)override
	{
		return amount;
	}
};

// =====================================================

class Order
{
private:
	std::unique_ptr<IDiscountStrategy> discountStrategy;
	double totalAmount;

public:
	Order(std::unique_ptr<IDiscountStrategy> Strategy)
	{
		discountStrategy = std::move(Strategy);
	}

	void AddItem(double price)
	{
		totalAmount += price;
	}

	double CalculateTotal()
	{
		return discountStrategy->ApplyDiscount(totalAmount);
	}
};

// =====================================================

int main()
{
	Order order1(std::make_unique<FixedDiscountStrategy>(10));
	order1.AddItem(50);
	order1.AddItem(30);
	double total1 = order1.CalculateTotal();
	std::cout << "์ฒซ ๋ฒˆ์งธ ์ฃผ๋ฌธ์˜ ์ด์•ก : " << total1 << " ๋‹ฌ๋Ÿฌ" << std::endl;

	Order order2(std::make_unique<PercentageDiscountStrategy>(20));
	order2.AddItem(100);
	order2.AddItem(75);
	double total2 = order2.CalculateTotal();
	std::cout << "๋‘ ๋ฒˆ์งธ ์ฃผ๋ฌธ์˜ ์ด์•ก : " << total2 << " ๋‹ฌ๋Ÿฌ" << std::endl;

	Order order3(std::make_unique<NoDiscountStrategy>());
	order3.AddItem(40);
	double total3 = order3.CalculateTotal();
	std::cout << "์„ธ ๋ฒˆ์งธ ์ฃผ๋ฌธ์˜ ์ด์•ก : " << total3 << " ๋‹ฌ๋Ÿฌ" << std::endl;

	return 0;
}

๐Ÿ“Œ ์ถœ๋ ฅ๊ฒฐ๊ณผ

profile
Unreal 1๊ธฐ

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด