1.1. Abstract Factory

1.1.1. Scopo

Crea una serie di oggetti correlati o dipendenti tra loro senza specificare le loro classi concrete. Solitamente le classi create implementano tutte la medesima interfaccia. Il client che usa l’Abstract Factory non conosce come questi oggetti vengano creati ma solamente come vanno assemblati insieme.

1.1.2. Diagramma UML

Alt AbstractFactory UML Diagram

1.1.3. Codice

Potete trovare questo codice anche su 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}