PHP之工厂方法模式(三)
定义
定义一个用于创建对象的接口(抽象工厂类),让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类(抽象工厂类的子类)。
工厂方法模式是简单工厂模式的进一步抽象和推广。在简单工厂模式中,当新增一个类时都需要改动一次工厂类方法。而工厂方法模式中将一个类的实例化延续到抽象工厂的子类,使得新增一个类时只需创建一个对应的工厂类即可。因此工厂方法模式符合开闭原则。
使用场景
工厂方法模式更适合需要创建一系列实例的场景。工厂方法模式的特点是将简单工厂模式的内部逻辑判断移到了客户端代码中进行,也就是工厂方法模式是通过在客户端决定实例化哪一个具体工厂来创建相应的实例的类对象。
如这样一个场景:几个大学生学雷锋做好事,帮一个老人家做家务活。分别用简单工厂模式和工厂方法模式实现如下:
//简单工厂模式
$leiFengA = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengA->BuyRice();
$leiFengB = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengB->Sweep();
$leiFengC = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengC->Wash();
//工厂方法模式
$factory = new UndergraduateFactory();
$leiFengA = factory->CreateLeiFeng();
$leiFengA->BuyRice();
$leiFengB = factory->CreateLeiFeng();
$leiFengB->Sweep();
$leiFengC = factory->CreateLeiFeng();
$leiFengC->Wash();
如果这时有个需求,由于大学生们毕业了各奔东西,没法再帮老人家做家务活了,需要由社区志愿者来代替他们做好事。那么修改上面客户端代码时,简单工厂模式需要将所有的“学雷锋的大学生”替换成社区志愿者。而工厂方法模式中,只需要将UndergraduateFactory()(学雷锋的大学生工厂)换成VolunteerFactory()(社区志愿者工厂)。
类图
PHP代码示例
//雷锋类
class LeiFeng
{
public function sweep()
{
echo '扫地';
}
public function wash()
{
echo '洗衣';
}
public function buyRice()
{
echo '买米';
}
}
//大学生
class Undergraduate extends LeiFeng
{
}
//社区志愿者
class Volunteer extends LeiFeng
{
}
//雷锋工厂类
abstract class LeiFengFactory
{
abstract public function createLeiFeng();
}
//学雷锋的大学生工厂类
class UndergraduateFactory extends LeiFengFactory
{
public function createLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂类
class VolunteerFactory extends LeiFengFactory
{
public function createLeiFeng()
{
return new Volunteer();
}
}
//客户端
$factory = new UndergraduateFactory();
$leiFeng = $factory->createLeiFeng();
$leiFeng->sweep();