1.8. Static Factory
1.8.1. Purpose
Similar to the AbstractFactory, this pattern is used to create series of
related or dependent objects. The difference between this and the
abstract factory pattern is that the static factory pattern uses just
one static method to create all types of objects it can create. It is
usually named factory
or build
.
1.8.2. UML Diagram
1.8.3. Code
You can also find this code on 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. Test
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}