1.1. Abstract Factory

1.1.1. Purpose

To create series of related or dependent objects without specifying their concrete classes. Usually the created classes all implement the same interface. The client of the abstract factory does not care about how these objects are created, it just knows how they go together.

1.1.2. UML Diagram

Alt AbstractFactory UML Diagram

1.1.3. Code

You can also find this code on GitHub

WriterFactory.php

1<?php
2
3namespace DesignPatterns\Creational\AbstractFactory;
4
5interface WriterFactory
6{
7    public function createCsvWriter(): CsvWriter;
8    public function createJsonWriter(): JsonWriter;
9}

CsvWriter.php

1<?php
2
3namespace DesignPatterns\Creational\AbstractFactory;
4
5interface CsvWriter
6{
7    public function write(array $line): string;
8}

JsonWriter.php

1<?php
2
3namespace DesignPatterns\Creational\AbstractFactory;
4
5interface JsonWriter
6{
7    public function write(array $data, bool $formatted): string;
8}

UnixCsvWriter.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class UnixCsvWriter implements CsvWriter
 6{
 7    public function write(array $line): string
 8    {
 9        return join(',', $line) . "\n";
10    }
11}

UnixJsonWriter.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class UnixJsonWriter implements JsonWriter
 6{
 7    public function write(array $data, bool $formatted): string
 8    {
 9        $options = 0;
10
11        if ($formatted) {
12            $options = JSON_PRETTY_PRINT;
13        }
14
15        return json_encode($data, $options);
16    }
17}

UnixWriterFactory.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class UnixWriterFactory implements WriterFactory
 6{
 7    public function createCsvWriter(): CsvWriter
 8    {
 9        return new UnixCsvWriter();
10    }
11
12    public function createJsonWriter(): JsonWriter
13    {
14        return new UnixJsonWriter();
15    }
16}

WinCsvWriter.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class WinCsvWriter implements CsvWriter
 6{
 7    public function write(array $line): string
 8    {
 9        return join(',', $line) . "\r\n";
10    }
11}

WinJsonWriter.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class WinJsonWriter implements JsonWriter
 6{
 7    public function write(array $data, bool $formatted): string
 8    {
 9        $options = 0;
10
11        if ($formatted) {
12            $options = JSON_PRETTY_PRINT;
13        }
14
15        return json_encode($data, $options);
16    }
17}

WinWriterFactory.php

 1<?php
 2
 3namespace DesignPatterns\Creational\AbstractFactory;
 4
 5class WinWriterFactory implements WriterFactory
 6{
 7    public function createCsvWriter(): CsvWriter
 8    {
 9        return new WinCsvWriter();
10    }
11
12    public function createJsonWriter(): JsonWriter
13    {
14        return new WinJsonWriter();
15    }
16}

1.1.4. Test

Tests/AbstractFactoryTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\AbstractFactory\Tests;
 6
 7use DesignPatterns\Creational\AbstractFactory\CsvWriter;
 8use DesignPatterns\Creational\AbstractFactory\JsonWriter;
 9use DesignPatterns\Creational\AbstractFactory\UnixWriterFactory;
10use DesignPatterns\Creational\AbstractFactory\WinWriterFactory;
11use DesignPatterns\Creational\AbstractFactory\WriterFactory;
12use PHPUnit\Framework\TestCase;
13
14class AbstractFactoryTest extends TestCase
15{
16    public function provideFactory()
17    {
18        return [
19            [new UnixWriterFactory()],
20            [new WinWriterFactory()]
21        ];
22    }
23
24    /**
25     * @dataProvider provideFactory
26     */
27    public function testCanCreateCsvWriterOnUnix(WriterFactory $writerFactory)
28    {
29        $this->assertInstanceOf(JsonWriter::class, $writerFactory->createJsonWriter());
30        $this->assertInstanceOf(CsvWriter::class, $writerFactory->createCsvWriter());
31    }
32}