1.9. Fabryka statyczna (Static Factory)

1.9.1. Przeznaczenie

Wzorzec Fabryki statycznej jest bardzo podobny do wzorca Fabryki abstrakcyjnej i pozwala na tworzenie powiązanych lub zależnych obiektów. W porównaniu z Fabryką abstrakcyjną, Fabryka statyczna używa jednej metody statycznej do tworzenia wszystkich typów obiektów, jakie może tworzyć. Zwykle taka metoda nazywa się factory lub build.

1.9.2. Przykłady

  • Zend Framework: Zend_Cache_Backend i _Frontend używa fabryki do stworzenia cache’u typu frontend i backend.

1.9.3. Diagram UML

Alt StaticFactory UML Diagram

1.9.4. Kod

Ten kod znajdziesz również na GitHub.

StaticFactory.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

namespace DesignPatterns\Creational\StaticFactory;

/**
 * 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
{
    /**
     * @param string $type
     *
     * @return FormatterInterface
     */
    public static function factory(string $type): FormatterInterface
    {
        if ($type == 'number') {
            return new FormatNumber();
        }

        if ($type == 'string') {
            return new FormatString();
        }

        throw new \InvalidArgumentException('Unknown format given');
    }
}

FormatterInterface.php

1
2
3
4
5
6
7
<?php

namespace DesignPatterns\Creational\StaticFactory;

interface FormatterInterface
{
}

FormatString.php

1
2
3
4
5
6
7
<?php

namespace DesignPatterns\Creational\StaticFactory;

class FormatString implements FormatterInterface
{
}

FormatNumber.php

1
2
3
4
5
6
7
<?php

namespace DesignPatterns\Creational\StaticFactory;

class FormatNumber implements FormatterInterface
{
}

1.9.5. Testy

Tests/StaticFactoryTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

namespace DesignPatterns\Creational\StaticFactory\Tests;

use DesignPatterns\Creational\StaticFactory\StaticFactory;
use PHPUnit\Framework\TestCase;

class StaticFactoryTest extends TestCase
{
    public function testCanCreateNumberFormatter()
    {
        $this->assertInstanceOf(
            'DesignPatterns\Creational\StaticFactory\FormatNumber',
            StaticFactory::factory('number')
        );
    }

    public function testCanCreateStringFormatter()
    {
        $this->assertInstanceOf(
            'DesignPatterns\Creational\StaticFactory\FormatString',
            StaticFactory::factory('string')
        );
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testException()
    {
        StaticFactory::factory('object');
    }
}