讓簡單工廠模式遵循開放封閉原則 (OCP)

Vanry發表於2017-04-01

常用的簡單工廠模式一般都是在工廠內部建立物件,缺點是判斷條件一般寫在工廠內部,如果要增刪改物件,就要開啟工廠,違反了開放封閉原則( 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 協議》,轉載必須註明作者和本文連結

相關文章