当多个类的定义类似,都有一定的方法需要实现,而其本身之间又有些许区别时,其实例化的操作可以不用直接实例化类本身,而将这个实例化的过程交给另一个部分去操作,即其工厂中去实现。
实现思路
定义一个创建对象的接口,让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
工厂 Fatory
在创建型模式中常常会遇到工厂这个词,在设计模式中,工厂通常指的是用于创建其他对象的对象,以用于实现不同的创建方案。
工厂对象通常包含一个或多个方法,用来创建这个工厂所能创建的各种类型的对象。这些方法可能接收参数,用来指定对象创建的方式,最后返回创建的对象。
代码实现
在本例中我们使用工厂方法模式定义 CarFactory 来制造不同的 Car,分别是 CarA 与 CarB。
定义工厂接口
工厂类中有produce
方法来产生实例化的类,传入的参数type
用于执行实例化哪种类
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
interface FactoryInterface
{
//定义工厂接口的produce方法用于实例化类
public function produce($type);
}
定义工厂
工厂类根据传入的不同参数在produce
方法中指定逻辑来实例化不同的Car,参数无效时抛出错误
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
class CarFactory implements FactoryInterface
{
//CarFactory类实现了Factory结构中的produce方法生产实例化Car
public function produce($type = '')
{
switch ($type) {
case 'A':
return new CarA();
break;
case 'B':
return new CarB();
break;
default:
echo "Type not support\n";
break;
}
}
}
Car类的定义
不同的Car根据面向对象的设计也分别实现了统一的Car接口,它们都实现了getType方法以返回自身的类型
CarInterface.php
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
interface CarInterface
{
//定义了Car的接口,每种Car必须要实现getType()方法以获取其类型
public function getType();
}
CarA.php
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
class CarA implements CarInterface
{
private $type = "Type A";
public function getType()
{
return $this->type;
}
}
CarB.php
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
class CarB implements CarInterface
{
private $type = "Type B";
public function getType()
{
return $this->type;
}
}
测试
在需要不同的Car时,我们只需要实例化一个CarFactory,然后调用其produce方法,通过传入不同的参数来得到指定类型的实例。
<?php
namespace DesignPattern\CreationalPatterns\FactoryMethod;
class Test
{
public function run()
{
$factory = new CarFactory();
$car_a = $factory->produce('A');
$car_b = $factory->produce('B');
echo $car_a->getType() . "\n";
echo $car_b->getType() . "\n";
}
}