소프트웨어 공부/디자인패턴

팩토리 패턴(Factory Pattern)

야곰야곰+책벌레 2022. 4. 7. 19:10
728x90
반응형

간단한 팩토리(Simple Factory)는 디자인 패턴이라고 할 수는 없다. 프로그래밍을 하는 데 있어서 자주 쓰이는 관용구에 가깝다고 할 수 있다. 단지 워낙 자주 쓰이기 때문에 패턴이라고 표현하기도 한다. 모든 팩토리 패턴에서는 객체 생성을 캡슐화한다. 팩토리 메서드 패턴(Factory Method Pattern)에서는 서브클래스에서 어떤 클래스를 만들지를 결정하게 함으로써 객체 생성을 캡슐화한다.

 

팩토리 메서드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다. 팩토리 메서드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에 맡기는 것이다. 

위의 클래스 다이어그램을 보면, Creator 추상 클래스에서 객체를 만들기 위한 메서드, 즉 팩토리 메서드를 위한 인터페이스를 제공한다는 것을 알 수 있다. Creator 추상 클래스에 구현되어 있는 다른 메서드에서는 팩토리 메서드에 의해 생산된 제품을 가지고 필요한 작업을 처리한다. 하지만 실제 팩토리 메서드를 구현하고 제품(객체 인스턴스)을 만들어내는 일은 서브클래스에서만 할 수 있다.

생산저(Creator) 클래스

추상 생산자 클래스에 객체를 생산하기 위해 구현할 팩토리 메서드를 정의한다. 생산자 클래스에 추상 제품 클래스에 의존하는 코드가 들어있는 경우도 있다. 이 제품 클래스의 객체는 이 클래스의 서브클래스에 의해 만들어진다. 생산자 자체에서는 절대로 어떤 구상 제품 클래스가 만들어질지 미리 알 수 없다. 제품을 생산하는 클래스는 구상 생산자(Concrete Creator)라고 부른다.

class CPizzaStore
{
public:
	shared_ptr<CPizza> orderPizza(string type)
	{
		shared_ptr<CPizza> pizza;
		pizza = createPizza(type);
		pizza->prepare();
		pizza->bake();
		pizza->cut();
		pizza->box();

		return pizza;
	}
protected:
	virtual shared_ptr<CPizza> createPizza(string item) abstract;
};

class CNYPizzaStore : public CPizzaStore
{
public:
	shared_ptr<CPizza> createPizza(string item)
	{
		if (item == "cheese") return make_shared<CNYStyleCheesePizza>();
		return nullptr;
	}
};

제품(Product) 클래스

팩토리에서는 제품을 생산한다. PizzaStore에서는 Pizza를 생산한다. 구상 클래스에서는 피자 가게에서 만들어지는 피자들이다.

// PIZZA CLASS
class CPizza
{
protected:
	string name;
	string dough;
	string sauce;
	list<string> toppings;

public:
	void prepare()
	{
		cout << "Preparing" << name << endl;
		cout << "Tossing dough..." << endl;
		cout << "Adding sauce..." << endl;
		cout << "Adding toppings: ";

		for (auto it : toppings)
		{
			cout << "  " << it << endl;
		}
	}
	void bake()
	{
		cout << "Bake for 25 minute at 350" << endl;
	}
	void cut()
	{
		cout << "Cutting the pizza into diagonal slices" << endl;
	}
	void box()
	{
		cout << "Place pizza in official PizzaStore box";
	}
	string getName()
	{
		return name;
	}
};

class CNYStyleCheesePizza : public CPizza
{
public:
	CNYStyleCheesePizza()
	{
		name = "NY Style Sauce and Cheese Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";

		toppings.push_back("Grated Reggiano Cheese");
	}
};

class CChicagoStyleCheesePizza : public CPizza
{
public:
	CChicagoStyleCheesePizza()
	{
		name = "Chicago Style Deep Dish Cheese Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";

		toppings.push_back("Shredded Mozzarella Cheese");
	}
	void cut()
	{
		cout << "Cutting the pizza into square slices" << endl;
	}
};

FactoryPattern.zip
0.01MB

728x90
반응형