1.8. Статическая Фабрика (Static Factory)

1.8.1. Назначение

Подобно AbstractFactory, этот паттерн используется для создания ряда связанных или зависимых объектов. Разница между этим шаблоном и Абстрактной Фабрикой заключается в том, что Статическая Фабрика использует только один статический метод, чтобы создать все допустимые типы объектов. Этот метод, обычно, называется factory или build.

1.8.2. Диаграмма UML

Alt StaticFactory UML Diagram

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}