PHP设计模式-工厂系列(三)-抽象工厂模式

        前两节我们总结了 简单工厂模式 [ 附: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.

        我们可以看到,这个例子,有两大产品,一个是玩具,另一个是衣服。每一个主任管理的工厂都可以生产玩具,和衣服。玩具和衣服又有不同的款式。对于这种产品集的创建,用这种模式比较合适。我们把这种设计模式叫做抽象工厂模式。但它有一个缺点。就是产品族是有限的,而且必须是可控的(即需要自己有哪些产品)。这样其产品的扩展性不是很强。

         至此,工厂模式的三个模式都介绍完了。这三个模式都是创建型的设计模式,都有其适用范围。现在总结一下:

        简单工厂模式:也叫静态方法工厂,它适用于创建单类型的产品

        工厂方法模式:它创建一个抽象工厂类,各不同工厂均要实现此抽象工厂的创建方法,以此来实现不同产品的创建。

        抽象工厂方法模式:它创建一个抽象工厂类,指定可以创建各种不同类型的产品的方法。各实现工厂需实现这些方法,以创建与此相关的一批产品。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值