阅读(2200) (0)

PHP 抽象工厂模式

2022-03-21 11:18:40 更新

目的

创建一系列互相关联或依赖的对象时,不指定他们具体的类。因为这些创建的类通常都实现了同一个接口。抽象工厂的客户端并不关心对象是如何创建的,而只知道它们是怎样组合的。

UML 图

Alt AbstractFactory UML Diagram

代码

WriterFactory.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

interface WriterFactory{
    public function createCsvWriter(): CsvWriter;
    public function createJsonWriter(): JsonWriter;
}

CsvWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

interface CsvWriter{
    public function write(array $line): string;
}

JsonWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

interface JsonWriter{
    public function write(array $data, bool $formatted): string;
}

UnixCsvWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class UnixCsvWriter implements CsvWriter{
    public function write(array $line): string{
        return join(',', $line) . "\n";
    }
}

UnixJsonWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class UnixJsonWriter implements JsonWriter{
    public function write(array $data, bool $formatted): string{
        $options = 0;
        if ($formatted) {
            $options = JSON_PRETTY_PRINT;
        }
        return json_encode($data, $options);
    }
}

UnixWriterFactory.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class UnixWriterFactory implements WriterFactory{
    public function createCsvWriter(): CsvWriter{
        return new UnixCsvWriter();
    }
    public function createJsonWriter(): JsonWriter{
        return new UnixJsonWriter();
    }
}

WinCsvWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class WinCsvWriter implements CsvWriter{
    public function write(array $line): string{
        return join(',', $line) . "\r\n";
    }
}

WinJsonWriter.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class WinJsonWriter implements JsonWriter{
    public function write(array $data, bool $formatted): string{
        return json_encode($data, JSON_PRETTY_PRINT);
    }
}

WinWriterFactory.php

<?php
namespace DesignPatterns\Creational\AbstractFactory;

class WinWriterFactory implements WriterFactory{
    public function createCsvWriter(): CsvWriter{
        return new WinCsvWriter();
    }
    public function createJsonWriter(): JsonWriter{
        return new WinJsonWriter();
    }
}

测试

Tests/AbstractFactoryTest.php

<?php
declare(strict_types=1);

namespace DesignPatterns\Creational\AbstractFactory\Tests;

use DesignPatterns\Creational\AbstractFactory\CsvWriter;
use DesignPatterns\Creational\AbstractFactory\JsonWriter;
use DesignPatterns\Creational\AbstractFactory\UnixWriterFactory;
use DesignPatterns\Creational\AbstractFactory\WinWriterFactory;
use DesignPatterns\Creational\AbstractFactory\WriterFactory;
use PHPUnit\Framework\TestCase;

class AbstractFactoryTest extends TestCase{
    public function provideFactory(){
        return [
            [new UnixWriterFactory()],
            [new WinWriterFactory()]
        ];
    }

    /**
     * @dataProvider provideFactory
     */
    public function testCanCreateCsvWriterOnUnix(WriterFactory $writerFactory){
        $this->assertInstanceOf(JsonWriter::class, $writerFactory->createJsonWriter());
        $this->assertInstanceOf(CsvWriter::class, $writerFactory->createCsvWriter());
    }
}