抽象工厂模式

目的

创建一系列相关的或互相依赖的对象,而不需要指定它们的具体类。通常,创建的类都实现了相同的接口。抽象工厂的客户端并不关心这些对象是如何创建的,它只知道它们是如何结合在一起的。

UML 类图

抽象工厂模式类图

示例代码

WriterFactory.php

1
2
3
4
5
6
7
8
9
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

CsvWriter.php

1
2
3
4
5
6
7
8
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

JsonWriter.php

1
2
3
4
5
6
7
8
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

UnixCsvWriter.php

1
2
3
4
5
6
7
8
9
10
11
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

UnixJsonWriter.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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

1
2
3
4
5
6
7
8
9
10
11
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

WinJsonWriter.php

1
2
3
4
5
6
7
8
9
10
11
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

namespace DesignPatterns\Creational\AbstractFactory;

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

public function createJsonWriter(): JsonWriter
{
return new WinJsonWriter();
}
}

测试

Test/AbstractFactoryTest.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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
*
* @param WriterFactory $writerFactory
*/
public function testCanCreateCsvWriterOnUnix(WriterFactory $writerFactory)
{
$this->assertInstanceOf(JsonWriter::class, $writerFactory->createJsonWriter());
$this->assertInstanceOf(CsvWriter::class, $writerFactory->createCsvWriter());
}
}