02 02 2020

简单工厂模式

模式定义

简单工厂的作用是由一个工厂对象决定创建出哪一种产品类的实例,而不需要客户了解这个对象属于哪个具体的子类。简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。


简单工厂模式的优势

让对象的调用者和对象创建过程分离,当对象调用者需要对象时,直接向工厂请求即可。从而避免了对象的调用者与对象的实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。


简单工厂模式的缺陷

当产品修改时,工厂类也要做相应的修改,违反了开-闭原则(对于扩展代码开放,对于类内修改关闭)。


代码实现

SimpleFactory\IShapre.class.php

<?php
namespace SimpleFactory;

/*
 * 接口,限定子类实现方法
 */
interface IShape
{
    public function draw();
}


SimpleFactory\Circle.class.php

<?php
namespace SimpleFactory;

/*
 * 实现类
 * 画圆
 */
class Circle implements IShape
{
    public function draw()
    {
        return "画一个圆形";
    }
}


SimpleFactory\Square.class.php

<?php
namespace SimpleFactory;

/*
 * 实现类
 * 画方
 */
class Square implements IShape
{
    public function draw()
    {
        return "画一个正方形";
    }
}


SimpleFactory\ShapeFactory.class.php

<?php
namespace SimpleFactory;

/*
 * 简单工厂类
 */
class ShapeFactory {

    const CIRCLE = 'circle';
    const SQUARE = 'square';

    private $shape;

    public function __construct($shape)
    {
        $this->shape = $shape;
    }

    /*
     * 根据初始化传参,实例化不同的实现类
     */
    public function getShape()
    {
        switch ($this->shape){
            case self::CIRCLE:
                return new Circle();
                break;
            case self::SQUARE:
                return new Square();
                break;
            default:
                return null;
        }
    }
}


SimpleFactory\SimpleFactoryTest.php

<?php
/*
 * 用于测试简单工厂模式
 */

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

use SimpleFactory\ShapeFactory;

$shapeFactory = new ShapeFactory(ShapeFactory::SQUARE);
$shape = $shapeFactory->getShape();

$result = $shape->draw();

echo $result;


测试

php SimpleFactory/SimpleFactoryTest.php 

输出:画一个正方形

总结

采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;缺点是可实例化的类型在编译期间已经被确定,如果增加新类型,则需要修改工厂,不符合OCP(开闭原则)的原则。简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。



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