让简单工厂模式遵循开放封闭原则 (OCP)

常用的简单工厂模式一般都是在工厂内部创建对象,缺点是判断条件一般写在工厂内部,如果要增删改对象,就要打开工厂,违反了开放封闭原则( Open Closed Principle )。

我们可以使用注册树模式将要注册的对象从外部注册到工厂内部,从而实现开放封闭。

<?php

class Factory
{
    protected $items;

    public function __construct(array $items = [])
    {
        $this->items = $items;
    }

    public function register($key, $value = null)
    {
        if (is_array($key)) {
            foreach ($key as $alias => $class) {
                $this->register($alias, $class);
            }
        } else {
            $this->items[$key] = $value;
        }

    }

    public function create($key)
    {
        if (array_key_exists($key, $this->items)) {
            return new $this->items[$key];
        }

        throw new InvalidArgumentException("Key [{$key}] is not registered.");
    }
}

// Test

$factory = new Factory;

$factory->register('std', StdClass::class);
$factory->register('dom', DOMDocument::class);
$factory->register('exception', Exception::class);

$classes = [
    'time' => DateTime::class,
    'queue' => SplQueue::class,
    'array' => ArrayObject::class,
];

$factory->register($classes);

var_dump(
    $factory->create('dom'),
    $factory->create('queue'),
    $factory->create('exception')
);

要是再使用反射将对象实例化时 constructor 的参数传进去就更强大了,感觉有点 Laravel 服务容器的感觉。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 6

感觉不错哦! 最近正好在学习设计模式

7年前 评论

这是注册表模式,不是工厂模式

7年前 评论

这样变成容器了

7年前 评论

工厂的产出一定的继承同一父类,或者实现同一接口的类的对象

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!