์ ๋ต ํจํด์ ๊ฐ์ฒด์ ํ์๋ฅผ ๋ฐ๊พธ๊ณ ์ถ์ ๋, ์ง์ ์์ ํ๋ ๊ฒ์ด ์๋๋ผ ์ ๋ต ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ๊ต์ฒดํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๋ ๋์์ธ ํจํด์ธ๋ค. ์ด๋ ๊ฐ์ฒด ์งํฅ์ ๊ฐ๋ฐฉ-ํ์์์น OCP์ ๋ฐ๋ฅด๋ฉฐ, ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๋ ๋ฐ ๋์์ด ๋๋ค.
์ด๋ฒ ๊ณผ์ ๋ ์์ ์ค์ ์ค๋ช ํ๋ ์ค๋ฆฌ, ์์ ์์ ๋ฅผ C++ ์ ๋ต ํจํด์ผ๋ก ๊ตฌํํ์ฌ ์ถ๋ ฅ๊น์ง ํด๋ณด๋ ๊ฒ์ด๋ค.
#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 ๋ฉ์๋๋ค์ ๊ตฌํ๋ถ์์ ์กฐ๊ฑด๋ฌธ์ ๋ง๋ค์ด๋์๋ค.
#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;
}