1.3.1. 目的
對比簡單工廠模式的優(yōu)點是,您可以將其子類用不同的方法來創(chuàng)建一個對象理朋。
舉一個簡單的例子绩蜻,這個抽象類可能只是一個接口铣墨。
這種模式是「真正」的設(shè)計模式, 因為他實現(xiàn)了 S.O.L.I.D 原則中「D」的 「依賴倒置」办绝。
這意味著工廠方法模式取決于抽象類伊约,而不是具體的類。 這是與簡單工廠模式和靜態(tài)工廠模式相比的優(yōu)勢孕蝉。
1.3.2. UML 圖
1.3.3. 代碼
你可以在??GitHub?查看這段代碼
Logger.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
interface Logger
{
public function log(string $message);
}
StdoutLogger.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLogger implements Logger
{
public function log(string $message)
{
echo $message;
}
}
FileLogger.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class FileLogger implements Logger
{
/**
* @var string
*/
private $filePath;
public function __construct(string $filePath)
{
$this->filePath = $filePath;
}
public function log(string $message)
{
file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
}
}
LoggerFactory.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
interface LoggerFactory
{
public function createLogger(): Logger;
}
StdoutLoggerFactory.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLoggerFactory implements LoggerFactory
{
public function createLogger(): Logger
{
return new StdoutLogger();
}
}
FileLoggerFactory.php
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class FileLoggerFactory implements LoggerFactory
{
/**
* @var string
*/
private $filePath;
public function __construct(string $filePath)
{
$this->filePath = $filePath;
}
public function createLogger(): Logger
{
return new FileLogger($this->filePath);
}
}
1.3.4. 測試
Tests/FactoryMethodTest.php
<?php
namespace DesignPatterns\Creational\FactoryMethod\Tests;
use DesignPatterns\Creational\FactoryMethod\FileLogger;
use DesignPatterns\Creational\FactoryMethod\FileLoggerFactory;
use DesignPatterns\Creational\FactoryMethod\StdoutLogger;
use DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory;
use PHPUnit\Framework\TestCase;
class FactoryMethodTest extends TestCase
{
public function testCanCreateStdoutLogging()
{
$loggerFactory = new StdoutLoggerFactory();
$logger = $loggerFactory->createLogger();
$this->assertInstanceOf(StdoutLogger::class, $logger);
}
public function testCanCreateFileLogging()
{
$loggerFactory = new FileLoggerFactory(sys_get_temp_dir());
$logger = $loggerFactory->createLogger();
$this->assertInstanceOf(FileLogger::class, $logger);
}
}