关闭

设计模式 一 工厂方法Factory Method(工厂模式)

486人阅读 评论(0) 收藏 举报
<?php
/**
 * 工厂方法模式演变
 *
 * 比萨加盟店
 * 背景:随着比萨店的发展,有更多人想成为比萨加盟店。
 */


/**
 * 每家加盟店都可能想要提供不同风味的比萨(比方说纽约、芝加哥、加州),这受到了开店地点影响。
 */


/**
 * 我们已经有一个做法。。。
 * 如果利用SimpleFactory,写出三种不同的工厂,分别为NYPizzaFactory、ChicagoPizzaFactory、CaliforniaPizzaFactory,那么各地加盟店都有适合的工厂可以使用,这是一种做法。
 */

$NYPizzaFactory = new NYPizzaFactory();
$nyStore = new PizzaStore($NYPizzaFactory);
$nyStore->orderPizza("veggie");


$ChicagoPizzaFactory = new NYPizzaFactory();
$chicagoStore = new PizzaStore($ChicagoPizzaFactory);
$chicagoStore->orderPizza("veggie");


/**
 * 但是你想要多一些质量控制。。。。
 * 在推广SimpleFactory时,你发现加盟店的确是采用你的工厂创建比萨,但其他部分,却开始采用他们自创的流程。
 * 烘烤的做法有些差异、不要切片、使用其他厂商的盒子。
 */


/**
 * 让子类决定,给比萨店使用框架。
 * 有个做法可以让比萨制作活动局限于pizzaStore类,而同时又能让这些加盟店依然可以自由制作该区域的风味。
 * 所有做的事情,就是把 createPizza() 设置为“抽象方法”,然后为每个区域风味创建一个PizzaStore 的子类。
 * 抽象、接口实现多态。
 */

 abstract class PizzaStore {
	//public $factory;
	//public function __construct(SimpleFactory $simpleFactory ) {
	//	$this->factory = $simpleFactory;
	//}
	
	public function orderPizza($type) {		
		//为了让系统有弹性,我们很希望这是一个抽象类或接口。
		//$pizza = $this->factory->createPizza($type); //变化部分
		$pizza = $this->createPizza($type);

		$pizza->prepare(); //准备
		$pizza->bake(); //烘烤
		$pizza->cut(); //切片
		$pizza->box(); //包装
		return $pizza;
	}

	abstract public function createPizza($type);
}

/**
 * 现在已经有了PizzaStore 超类,让 NYPizzaStore,ChicagoPizzaStore等 都继承这个PizzaStore,由子类决定如何制作比萨。
 *
 */

/**
 * 子类如何做决定
 * 关于这个方面,需要从PizzaStore的orderPizza()方法观点来看,更进一步地,orderPizza()方法对pizza做了许多事情(准备、烘烤、切片、包装)
 * 但由于Pizza对象是抽象的,orderPizza()并不知道哪些实际的具体类参与了进来,这不是orderPizza()方法决定的,换句话,这就是解耦。
 * 那么,子类是实时作出这样的决定吗?不是,但从orderPizza()的角度来看,如果选择在NYStylePizzaStore订购比萨,就是由这个子类(NYStylePizzaStore)决定。
 * 严格来说,并非由这个子类实际做“决定”,而是由“顾客”决定到哪一家风味比萨店才决定了比萨风味。
 */

class NYPizzaStore extends PizzaStore {
	public function createPizza($type) {
		if ("cheese" == $type) {//奶酪比萨
			$pizza = new NYStyleCheesePizza(); 		
		} elseif ("greek" == $type) {//希腊比萨
			$pizza = new NYStyleGreekPizza();		
		} elseif ("pepperoni" == $type) {//香肠比萨
			$pizza = new NYStylePepperoniPizza();		
		} else {
			return null;
		}
		return $pizza;
	}
}

$NYPizzaStore = new NYPizzaStore();
$pizza = $NYPizzaStore->orderPizza('cheese');

/**
 * 注意 orderPizza 已经实现了createPizza
 */




 /**
  * 总结 
  * 工厂方法模式 定义了一个创建对象的接口,但由子类决定要实例化的类时哪一个。工厂方法让类把实例化推迟到子类。
  * 问:简单工厂与工厂方法的差异
  * 答:工厂方法是用继承扩展了一个类,而简单工厂,工厂是另一个pizzastore使用对象。
  * 子类的确看起来像简单工厂。简单工厂把全部的事情,在一个地方处理完了。然而工厂方法却是创建一个框架,让子类决定要如何实现。
  * 比方说,在工厂方法中,orderPizza()方法提供了一般框架,以便创建比萨。orderPizza()依赖工厂方法创建具体类,并制造出实际的比萨。
  */






参考资料 :Head First 设计模式


日志记录实例演化


设计模式目录


0
0

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