03 02 2020

工厂方法模式

模式定义

定义一个创建对象的接口,但是让子类去实例化具体类。工厂方法模式让类的实例化延迟到子类中。

工厂方法模式的优势

定义一个创建对象的接口,让子类决定哪个类实例化。 他可以解决简单工厂模式中的封闭开放原则问题。

代码示例

FactoryMethod\FactoryMethod.class.php
<?php
namespace FactoryMethod;

abstract class FactoryMethod
{
    const CHEAP = 1;
    const FAST = 2;

    abstract protected function createVehicle($type);

    public function create($type)
    {
        $obj = $this->createVehicle($type);
        $color = $obj->getColor();

        return $color;
    }
}


FactoryMethod\GermanFactory.class.php
<?php
namespace FactoryMethod;

class GermanFactory extends FactoryMethod
{
    protected function createVehicle($type)
    {
        switch ($type){
            case parent::CHEAP:
                return new Bicycle();
                break;
            case parent::FAST;
                $obj = new Porsche();
                $obj->addTuningAMG();

                return $obj;
                break;
            default:
                return null;
        }
    }
}


FactoryMethod\ItalianFactory.class.php
<?php
namespace FactoryMethod;

class ItalianFactory extends FactoryMethod
{
    protected function createVehicle($type)
    {
        switch ($type){
            case parent::CHEAP:
                return new Bicycle();
                break;
            case parent::FAST;
                return new Ferrari();
                break;
            default:
                return null;
        }
    }
}


FactoryMethod\VehicleInterface.class.php
<?php
namespace FactoryMethod;

interface VehicleInterface
{
    public function getColor();
}


FactoryMethod\Bicycle.class.php
<?php
namespace FactoryMethod;

class Bicycle implements VehicleInterface
{
    public function getColor()
    {
        return "color is green";
    }
}


FactoryMethod\Porsche.class.php
<?php
namespace FactoryMethod;

class Porsche implements VehicleInterface
{
    private $amg = '';

    public function getColor()
    {
        return "color is red" . $this->amg;
    }

    public function addTuningAMG()
    {
        $this->amg = " amg is porsche";
    }
}


FactoryMethod\Ferrari.class.php
<?php
namespace FactoryMethod;

class Ferrari implements VehicleInterface
{
    public function getColor()
    {
        return "color is blue";
    }
}


FactoryMethod\FactoryMethodTest.php
<?php
spl_autoload_register(function ($className){
   $className = str_replace('\\', '/', $className);
    include $className.".class.php";
});

use FactoryMethod\GermanFactory;
use FactoryMethod\ItalianFactory;

$germanFactory = new GermanFactory();
$italianFactory = new ItalianFactory();

$germanResult1 = $germanFactory->create(\FactoryMethod\FactoryMethod::CHEAP);
$germanResult2 = $germanFactory->create(\FactoryMethod\FactoryMethod::FAST);
$italianResult1 = $italianFactory->create(\FactoryMethod\FactoryMethod::CHEAP);
$italianResult2 = $italianFactory->create(\FactoryMethod\FactoryMethod::FAST);

echo $germanResult1 . "\n";
echo $germanResult2 . "\n";
echo $italianResult1 . "\n";
echo $italianResult2 . "\n";


测试示例:

php FactoryMethod/FactoryMethodTest.php 

// 输出
color is green
color is red amg is porsche
color is green
color is blue


总结

工厂方法模式和抽象工厂模式有点类似,但也有不同。 工厂方法针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例,在同一等级结构中,支持增加任意产品。 抽象工厂是应对产品族概念的,比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。




代码地址:https://github.com/798256478/design-patterns/tree/master/FactoryMethod