1.1. Factoría Abstracta

1.1.1. Propósito

Para crear una serie de objetos relacionados o dependientes sin especificar a qué clase concreta pertenecen. Normalmente las clases creadas implementan las mismas interfaces. El cliente de la factoría abstracta no necesita preocuparse por cómo estos objetos son creados, él solo sabe qué tiene que hacer con ellos.

1.1.2. Diagrama UML

Alt AbstractFactory UML Diagram

1.1.3. Código

Puedes encontrar el código en 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}