关闭

设计模式 一 抽象工厂Abstract Factory(工厂模式)

413人阅读 评论(0) 收藏 举报
<?php
/**
 * 原料家族
 *
 * 随着比萨店加盟店越来越多,有些加盟店为了提高利润,从而降低了原料的质量,所有总店必须采取一些措施,避免损害公司形象的品牌。
 */

/**
 * 措施:保持原料一致
 * 问题1:如何确保原料一致,打算建造一家生产原料的工厂,并送到各家加盟店。
 * 问题2:各个加盟店坐落在不同的区域,纽约的红酱料和芝加哥的红酱料是不一样的。
 * 所有让我们准备二组不同的原料。
 *
 */


 /**
  * 开始建造原料工厂
  * 现在,我们要建造一个工厂来生产原料;这个工厂将负责创建原料家族中的每一种原料。也就是说,工厂将要生产面团、酱料、芝士等
  * 待会儿,你就知道如何处理各个区域的差异了。
  */


/**
 * 先开始定义一个接口,这个接口负责创建所有的原料。
 *
 */

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

/**
 * 接下来要做的事情。
 * 1、为每一个区域建造一个工厂。你需要创建一个继承自IPizzaIngredientFactory 的子类来实现每一个创建方法。
 * 2、实现一组原料类提供工厂使用,例如ReggianoCheese(巴马干酪)、RedPeppers(红辣椒)、ThickCrustDough(厚面团),这些类可以在合适的区域间共享。
 * 3、然后你仍然需要将这一切组织起来,将新的原料工厂整合进旧的 PizzaStore(NYPizzaStore、ChicagoPizzaStore)代码中。
 */


 /**
  * 创建纽约原料工厂
  */
class NYPizzaIngredientFactory implements IPizzaIngredientFactory {
	public function createDough() {
		return new ThickCrustDough();
	}

	public function createSauce() {
		return new MarinaraSauce();
	}

	public function createCheese() {
		return new ReggianoCheese();
	}

	// 其他省略
}

/**
 * 创建芝加哥原料工厂
 */
class ChicagoPizzaIngredientFactory implements IPizzaIngredientFactory {
	public function createDough() {
		return new ThickCrustDough();
	}
	
	public function createSauce() {
		return new PlumTomatoSauce();
	}

	// 其他省略
}

/**
 * 重做比萨
 *
 * 原料工厂已经一切就绪,现在我们只需要重做比萨,好让它们只使用原料工厂生产出来的原料。我们先从抽象的Pizza类开始。
 */

 abstract class Pizza {
	public $name;
	public $price;
	public $dough;
	public $sauce;
	//省略其他原料成员。

	abstract public function prepare(); //主要抽象这个前期收集原料

	public function bake() {
		echo "baking";
	}

	public function cut() {
		echo "cutting";
	}

	// 其他操作省略
 }


/**
 * 继续重做比萨
 * 现在已经有了一个抽象比萨,可以开始创建纽约和芝加哥风味的比萨了。从今以后,加盟店必需直接从工厂取得原料,那些偷工减料的日子宣告结束了!
 * 我们曾经写过工厂方法的代码, 有NYCheesePizza 和 ChicagoCheesePizza类。比较下这两个类,唯一的差异在于使用区域性的原料,至于比萨做法都是一样的,
 * 它们都依循相同的准备步骤,只是使用不同的原料。
 * 所以,其实我们不需要设计两个不同的类来出来不同风味的比萨,让原料工厂处理这种差异就可以了。下面是CheesePizza。
 */

//奶酪比萨
class CheesePizza extends Pizza {
	public $ingredientFactory;
	public $dough;
	public $sauce;
	public $cheese;


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

	public function prepare() {
		$this->dough = $this->ingredientFactory->createDough();
		$this->sauce = $this->ingredientFactory->createSauce();
		$this->cheese = $this->ingredientFactory->createCheese();
	}
}


//蛤蜊比萨
class ClamPizza extends Pizza {
	public $ingredientFactory;
	public $dough;
	public $sauce;
	public $cheese;
	public $clam;

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

	public function prepare() {
		$this->dough = $this->ingredientFactory->createDough();
		$this->sauce = $this->ingredientFactory->createSauce();
		$this->cheese = $this->ingredientFactory->createCheese();
		$this->clam = $this->ingredientFactory->createCheese();
	}
}


/**
 * 再回到比萨店。
 *
 */

 
class NYPizzaStore extends PizzaStore {
	public function createPizza($type) {

		$ingredientFactory = new NYPizzaIngredientFactory();

		if ("cheese" == $type) {//奶酪比萨
			//$pizza = new NYStyleCheesePizza();
			$pizza = new CheesePizza($ingredientFactory);
		} elseif ("greek" == $type) {//希腊比萨
			//$pizza = new NYStyleGreekPizza();		
			$pizza = new GreekPizza($ingredientFactory);
		} elseif ("pepperoni" == $type) {//香肠比萨
			//$pizza = new NYStylePepperoniPizza();		
			$pizza = new PepperoniPizza($ingredientFactory);
		} else {
			return null;
		}
		return $pizza;
	}
}




/**
 * 总结
 * 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确具体类。
 *
 */




参考资料 :Head First 设计模式

参考其他 http://blog.csdn.net/calllmq/article/details/7335951


设计模式目录
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:98430次
    • 积分:1540
    • 等级:
    • 排名:千里之外
    • 原创:54篇
    • 转载:58篇
    • 译文:0篇
    • 评论:2条
    最新评论