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

<?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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值