前两节我们总结了 简单工厂模式 [ 附:PHP设计模式-简单工厂模式 ] 和 工厂方法模式 [ 附:PHP设计模式-工厂方法模式 ] 。 从最开始工厂领导任命主管生产各种类型的玩具,到每种类型的产品工厂主任的任命来生产不同款式的玩具。这让工厂收益丰厚。领导为什么是领导就是因为他有想法,他觉得,为了把工厂做得更大一点。他决定,不能单纯地生产玩具。每种玩具应该有一种附属的产品。例如,给玩具生产衣服,让孩子们能给自己喜爱的玩具穿上不同的衣服。于是命令发下去了。所以我们就需要新增这些类了。
class ToyCloth {
}
class DogCloth extends ToyCloth {
}
class CatCloth extends ToyCloth {
}
class BearCloth extends ToyCloth {
}
于是主管就向各主任发号施令了。每个车间主任不光要有造玩具的能力,还有造衣服的能力。原来只有一个make方法不够了。得有一个makeCloth()方法了。为了让原来的make方法更好理解,那改成makeToy()吧。看下现在这个职位的情况吧。
abstract class ToyManager {
//原来的make()方法
//abstract public function make($styleName);
//老的make()方法改为makeToy()方法
abstract public function makeToy($styleName);
//增加制造衣服的方法
abstract public function makeCloth($styleName);
}
各主任开始研究了,需要能管理车间,让他们造衣服。
class DogToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogCloth';
return new $className();
}
}
class BearToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogCloth';
return new $className();
}
}
class CatToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogCloth';
return new $className();
}
}
好了,研究完了。可以等老大发号施令了。老大也要改变下工作方式了。所有完整代码如下:
class DogToy {
}
class CatToy {
}
class BearToy {
}
class Style1DogToy extends DogToy {
}
class Style2DogToy extends DogToy {
}
class Style1CatToy extends CatToy {
}
class Style2CatToy extends CatToy {
}
class Style3CatToy extends CatToy {
}
class Style1BearToy extends BearToy {
}
class Style2BearToy extends BearToy {
}
class ToyCloth {
}
class DogCloth extends ToyCloth {
}
class Style1DogCloth extends DogCloth {
}
class CatCloth extends ToyCloth {
}
class BearCloth extends ToyCloth {
}
abstract class ToyManager {
//原来的make()方法
//abstract public function make($styleName);
//老的make()方法改为makeToy()方法
abstract public function makeToy($styleName);
//增加制造衣服的方法
abstract public function makeCloth($styleName);
}
class DogToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogCloth';
return new $className();
}
}
class BearToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'BearCloth';
return new $className();
}
}
class CatToyManager extends ToyManager {
public function makeToy($styleName)
{
$className = ucfirst(strtolower($styleName)).'DogToy';
return new $className();
}
public function makeCloth($styleName)
{
$className = ucfirst(strtolower($styleName)).'CatCloth';
return new $className();
}
}
class FactoryManager
{
//指定工厂可以生产的玩具和衣服类型
public static $allowToyName = array(
"bear", "cat", "dog"
);
//指定工厂可以生产的产品类型
public static $allowProductName = array(
'toy', 'cloth',
);
//你让我生产什么,告诉我是玩具还是衣服, 衣服和玩具的名字和款式
public static function make($productName, $toyName, $styleName)
{
//检查这种产品是否能生产
$productName = strtolower($productName);
if (!in_array($productName, self::$allowProductName)) {
throw new Exception("没法生产这种产品");
}
//检查这种玩具是否能生产
$toyName = strtolower($toyName);
if (!in_array($toyName, self::$allowToyName)) {
throw new Exception("没法生产这种玩具");
}
//先要找到车间主任
$managerName = $toyName."ToyManager";
$manager = new $managerName();
//告诉车间主任生产的产品及款式
$doName = "make".ucfirst($productName);
return $manager->$doName($styleName);
}
}
于是,我们主管要生产一个产品可以:$style1DogCloth = FactoryManager::make('Cloth', 'Dog', 'Style1');这样就可以生产一件狗玩具的衣服,款式为1.
我们可以看到,这个例子,有两大产品,一个是玩具,另一个是衣服。每一个主任管理的工厂都可以生产玩具,和衣服。玩具和衣服又有不同的款式。对于这种产品集的创建,用这种模式比较合适。我们把这种设计模式叫做抽象工厂模式。但它有一个缺点。就是产品族是有限的,而且必须是可控的(即需要自己有哪些产品)。这样其产品的扩展性不是很强。
至此,工厂模式的三个模式都介绍完了。这三个模式都是创建型的设计模式,都有其适用范围。现在总结一下:
简单工厂模式:也叫静态方法工厂,它适用于创建单类型的产品
工厂方法模式:它创建一个抽象工厂类,各不同工厂均要实现此抽象工厂的创建方法,以此来实现不同产品的创建。
抽象工厂方法模式:它创建一个抽象工厂类,指定可以创建各种不同类型的产品的方法。各实现工厂需实现这些方法,以创建与此相关的一批产品。