티스토리 뷰


 추상 팩토리 패턴
* 추상적인 인터페이스를 이용하여, 여러가지(다형) 변화 돼는 것들을 세분하 한다.

예를 들면 )

* 피자 를 만들기 위해서 재료가 여러가지가 필요하며, 재료나 첨가물에 따라 피자 스타일이 다르다.
 (피자가계마다 피자는 종류는 다양하다. )

* 재료, 첨가물을 생성하는 인터페이스를 작성하고,  피자 만들 때 작성한 인터페이스를  인스턴스를 주입하여 변화에 대응하는 다양한  피자를 만들수 있게끔 한다.

예를 들면) 

나와 미연은 시카고피자에 가서 샐러드, 고구마 피자를 주문

시자고 피자 에서는 주문접수를 받고 샐러드 피자, 고무마 피자에  필요한 재료 가져오고  피자에 재료 셋팅 하고,

굽고, 자르고, 주문한 피자를 고객에게 드립니다.

여기서, 중요한 건

샐러드 피자 내에서  재료를 직접 구현하지 않고 , 필요한 재료 (인터페이스) 가져와서 재료를 구현하다.
고구마 피자 내에서도 마찬가지로 , 필요한 재료 (인터페이스) 가져와서 재료를 구현하다.


의존성 주입

* new testPizza()  구현 한 것이 아니 createPizaa('test')  과 같이 추상적이도록 한다.

그리고 , createPizza 안에 서 객체가 의존적이지 않고 ,

내부에서 생성해야 할 것들을 인터페이스 지정하여, 세분화 시키는 것을  의존성 주입이라고 개인적으로 생각 .


// 추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 개체를 구상 클래스를 지정 하지 않고도 생성할 수 있습니다
// 추상 팩토리 패턴은 본격적으로 인터페이스와 업 캐스팅을 통해서 객체 자동생성을 구현하게 되고,
// 그것을 통해 생산성과 직접적인 연관을 가지게 됩니다. 결국 높은 객체 생산 효율을 추구하는 디자인 패턴인 것이죠.
//
/*

이어지는 피자가게 프랜차이즈 스토리에 대한 설명을 약간 해야 할 것 같습니다.
객체마을 피자가게가 인기가 올라가자 뉴욕과 시카고에 분점을 내기로 한 것까지가 지난번 팩토리메서드의 이야기였습니다.

그런데 일부 분점에서는 자잘한 재료를 더 싼 재료로 바꿔서 원가를 줄이고 마진을 올리고 있다는 정보를 들어왔습니다.
이런 현상이 심해지면 객체마을 피자 브랜드의 품질에 타격이 올 수 있기 때문에 각 분점에서 임의로 재료를
공급해서 조달하는 것을 막고자 하는 것이 이번 추상 팩토리 패턴의 목적 입니다.
*/

interface IPizzaIngredientFactory
{
	public function createDough();
	public function createSauce();
	public function createCheese();
	public function createVeggies();
	public function createPepperoni();
	public function createClam();
}

class NYPizzaIngredientFactory implements IPizzaIngredientFactory
{
	function createDough()
	{
		return " 이마트 도우 ";
	}

	function createSauce()
	{
		//return new EmartSource();
		//return new HimartSoure();
		return "   이마트 소스 ";
	}

	function createCheese()
	{
		return "   이마트 치즈 ";
	}

	function createVeggies()
	{
		return "   이마트 야채 ";
	}

	function createPepperoni()
	{
		return "   하이마트 페페로니  ";
	}

	function createClam()
	{
		return "   재주도산 조개  ";
	}
}

class ChicagoPizzaIngredientFactory implements IPizzaIngredientFactory
{
	function createDough()
	{
		return " 시카고 도우 ";
	}

	function createSauce()
	{
		//return new EmartSource();
		//return new HimartSoure();
		return "   시카고 소스 ";
	}

	function createCheese()
	{
		return "   시카고 치즈 ";
	}

	function createVeggies()
	{
		return "   이마트 야채 ";
	}

	function createPepperoni()
	{
		return "   하이마트 페페로니  ";
	}

	function createClam()
	{
		return "   재주도산 조개  ";
	}
}


// 생산자
abstract class PizzaStore
{
	public $_pizza;

	function orderPizza($pizzaStyle)
	{
		$pizza = $this->createPizza($pizzaStyle);
		$pizza->prepare();
		$pizza->bake();
		$pizza->cut();
		$pizza->box();

		return $pizza;
	}

	abstract function createPizza($pizzaStyle); //팩토리 메소드
}

class NYPizzaStore extends PizzaStore
{
	public $_ingredientFactory;

	function __construct()
	{
		$this->_ingredientFactory = new NYPizzaIngredientFactory();
	}

	function createPizza($style)
	{
		switch($style) {
			case 'cheese':
				$this->_pizza = new CheesePizza($this->_ingredientFactory);
				$this->_pizza->setName("뉴욕스타일 치즈피자");
				break;
			case 'pepperoni':
				$this->_pizza = new PepperoniPizza($this->_ingredientFactory);
				$this->_pizza->setName("뉴욕스타일 페페로니피자");
				break;
			case 'clam':
				$this->_pizza = new CalmPizza($this->_ingredientFactory);
				$this->_pizza->setName("뉴욕스타일 조개피자");
				break;
			case 'veggie':
				$this->_pizza = new VeggiePizza($this->_ingredientFactory);
				$this->_pizza->setName("뉴욕스타일 야체피자");
				break;
		}

		return $this->_pizza;
	}

}

class ChicagoPizzStore extends PizzaStore
{
	function __construct()
	{
		$this->_ingredientFactory = new ChicagoPizzaIngredientFactory();
	}

	function createPizza($style)
	{
		switch($style) {
			case 'cheese':
				$this->_pizza = new CheesePizza($this->_ingredientFactory);
				$this->_pizza->setName("시카고 치즈피자");
				break;
			case 'pepperoni':
				$this->_pizza = new PepperoniPizza($this->_ingredientFactory);
				$this->_pizza->setName("시카고 페페로니피자");
				break;
			case 'clam':
				$this->_pizza = new CalmPizza($this->_ingredientFactory);
				$this->_pizza->setName("시카고 조개피자");
				break;
			case 'veggie':
				$this->_pizza = new VeggiePizza($this->_ingredientFactory);
				$this->_pizza->setName("시카고 야체피자");
				break;
		}

		return $this->_pizza;
	}
}

//제품
abstract class Pizza
{
	public $_name;
	public $_dough;
	public $_sauce;
	public $_veggies = array();
	public $_cheese;
	public $_pepperoni;
	public $_clam;

	public function getName()
	{
		return $this->_name;
	}

	public function setName($name)
	{
		$this->_name = $name;
	}

	function  bake()
	{
		echo "피자를 굽습니다. : " . $this->getName();
	}

	function  cut()
	{
		echo "피자를 자릅니다. : " . $this->getName();
	}

	function  box()
	{
		echo "피자를 포장합니다. : " .  $this->getName();
	}

	public function __toString()
	{
		$display = "";
		$dispaly .= "----------" . $this->getName() . "를 준비합니다. ---------";

		if($this->_dough) $dispaly .= "도우 반주중 .. : " . $this->_dough;
		if($this->_sauce) $dispaly .= "소스 추가중 .. : " . $this->_sauce;
		if($this->_cheese) $dispaly .= "치즈 반주중 .. : " . $this->_cheese;
		if($this->_pepperoni) $dispaly .= "페페로니추가중 .. : " . $this->_pepperoni;
		if($this->_clam)   $dispaly .= "조개  추가중 .. : " . $this->_clam;

		return $dispaly;
	}

	abstract function prepare();

}

class CheesePizza extends Pizza
{
	public $_ingredientFactory;


	public function __construct($ingredientFactory)
	{
		$this->_ingredientFactory = $ingredientFactory;
	}

	public function prepare()
	{
		echo "피자 주문 접수 . : " . $this->getName();
		$this->_dough  = $this->_ingredientFactory->createDough();
		$this->_sauce  = $this->_ingredientFactory->createSauce();
		$this->_cheese = $this->_ingredientFactory->createCheese();
		$this->_clam = $this->_ingredientFactory->createClam();
		echo $this->__toString();
	}


}


class CalmPizza extends Pizza
{

	public $_ingredientFactory;


	public function __construct($ingredientFactory)
	{
		$this->_ingredientFactory = $ingredientFactory;
	}

	public function prepare()
	{
		echo "피자 주문 접수 . : " . $this->getName();
		$this->_dough  = $this->_ingredientFactory->createDough();
		$this->_sauce  = $this->_ingredientFactory->createSauce();
		$this->_cheese = $this->_ingredientFactory->createCheese();
		$this->_clam = $this->_ingredientFactory->createClam();
		echo $this->__toString();
	}


}

$nyStore = new NYPizzaStore();
$chicagoStore = new ChicagoPizzStore();

$pizza   = $nyStore->orderPizza("cheese");
echo "주문한 피자가 나왔습니다 : " . $pizza->getName();

$pizza   = $chicagoStore->orderPizza("clam");
echo "주문한 피자가 나왔습니다 : " . $pizza->getName();
저작자 표시
신고

'웹개발 > Php' 카테고리의 다른 글

XDEBUG PROFILE  (0) 2010.12.15
PHP 매직 메소드  (0) 2010.11.25
Php Session 정보  (0) 2010.11.24
추상 팩토리 패턴 그리고 의존성 주입에 대한 내 생각  (0) 2010.09.03
PHP CURL 정리  (953) 2010.09.01
데코레이터 패턴 정리  (0) 2010.07.05
댓글
댓글쓰기 폼