1.8. Статична фабрика

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}