與 抽象工廠 類似,靜態(tài)工廠模式用于創(chuàng)建一系列互相關(guān)聯(lián)或依賴的對象。它與抽象工廠模式的區(qū)別在于,靜態(tài)工廠模式僅使用 一個(gè)靜態(tài)方法 來創(chuàng)建所有它可以創(chuàng)建的類型。通常,這個(gè)靜態(tài)方法被命名為:factory 或 build。
StaticFactory.php
<?php
declare(strict_types=1);
namespace DesignPatterns\Creational\StaticFactory;
use InvalidArgumentException;
/**
* Note1: Remember, static means global state which is evil because it can't be mocked for tests
* Note2: Cannot be subclassed or mock-upped or have multiple different instances.
*/
final class StaticFactory
{
public static function factory(string $type): Formatter
{
if ($type == 'number') {
return new FormatNumber();
} elseif ($type == 'string') {
return new FormatString();
}
throw new InvalidArgumentException('Unknown format given');
}
}
Formatter.php
<?php
declare(strict_types=1);
namespace DesignPatterns\Creational\StaticFactory;
interface Formatter
{
public function format(string $input): string;
}
FormatString.php
<?php
declare(strict_types=1);
namespace DesignPatterns\Creational\StaticFactory;
class FormatString implements Formatter
{
public function format(string $input): string
{
return $input;
}
}
FormatNumber.php
<?php
declare(strict_types=1);
namespace DesignPatterns\Creational\StaticFactory;
class FormatNumber implements Formatter
{
public function format(string $input): string
{
return number_format((int) $input);
}
}
Tests/StaticFactoryTest.php
<?php
declare(strict_types=1);
namespace DesignPatterns\Creational\StaticFactory\Tests;
use InvalidArgumentException;
use DesignPatterns\Creational\StaticFactory\FormatNumber;
use DesignPatterns\Creational\StaticFactory\FormatString;
use DesignPatterns\Creational\StaticFactory\StaticFactory;
use PHPUnit\Framework\TestCase;
class StaticFactoryTest extends TestCase
{
public function testCanCreateNumberFormatter()
{
$this->assertInstanceOf(FormatNumber::class, StaticFactory::factory('number'));
}
public function testCanCreateStringFormatter()
{
$this->assertInstanceOf(FormatString::class, StaticFactory::factory('string'));
}
public function testException()
{
$this->expectException(InvalidArgumentException::class);
StaticFactory::factory('object');
}
}
更多建議: