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}