1.8. 静态工厂
1.8.1. 目的
与 抽象工厂 类似,静态工厂模式用于创建一系列互相关联或依赖的对象。它与抽象工厂模式的区别在于,静态工厂模式仅使用 一个静态方法 来创建所有它可以创建的类型。通常,这个静态方法被命名为:factory
或 build
。
1.8.2. UML 图

1.8.3. 代码
你可以在 GitHub 上找到这些代码
StaticFactory.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\StaticFactory;
6
7use InvalidArgumentException;
8
9/**
10 * Note1: Remember, static means global state which is evil because it can't be mocked for tests
11 * Note2: Cannot be subclassed or mock-upped or have multiple different instances.
12 */
13final class StaticFactory
14{
15 public static function factory(string $type): Formatter
16 {
17 return match ($type) {
18 'number' => new FormatNumber(),
19 'string' => new FormatString(),
20 default => throw new InvalidArgumentException('Unknown format given'),
21 };
22 }
23}
Formatter.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\StaticFactory;
6
7interface Formatter
8{
9 public function format(string $input): string;
10}
FormatString.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\StaticFactory;
6
7class FormatString implements Formatter
8{
9 public function format(string $input): string
10 {
11 return $input;
12 }
13}
FormatNumber.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\StaticFactory;
6
7class FormatNumber implements Formatter
8{
9 public function format(string $input): string
10 {
11 return number_format((int) $input);
12 }
13}
1.8.4. 测试
Tests/StaticFactoryTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\StaticFactory\Tests;
6
7use InvalidArgumentException;
8use DesignPatterns\Creational\StaticFactory\FormatNumber;
9use DesignPatterns\Creational\StaticFactory\FormatString;
10use DesignPatterns\Creational\StaticFactory\StaticFactory;
11use PHPUnit\Framework\TestCase;
12
13class StaticFactoryTest extends TestCase
14{
15 public function testCanCreateNumberFormatter()
16 {
17 $this->assertInstanceOf(FormatNumber::class, StaticFactory::factory('number'));
18 }
19
20 public function testCanCreateStringFormatter()
21 {
22 $this->assertInstanceOf(FormatString::class, StaticFactory::factory('string'));
23 }
24
25 public function testException()
26 {
27 $this->expectException(InvalidArgumentException::class);
28
29 StaticFactory::factory('object');
30 }
31}