1.3. Metoda wytwórcza (Factory Method)¶
1.3.1. Przeznaczenie¶
Przewagą Metody wytwórczej nad Fabryką uproszczoną jest możliwość implementowania różnych sposobów tworzenia obiektów poprzez dziedziczenie po klasie Metody wytwórczej.
W prostych przypadkach zamiast klasy abstrakcyjnej można użyć zwykłego interfejsu.
Ten wzorzec implementuje jedną z podstawowych zasad programowania obiektowego SOLID - „D” - zasadę odwrócenia zależności (ang. Dependency inversion principle).
Oznacza to, że klasa FactoryMethod
opiera się na abstrakcji, a nie na konkretnej implementacji. Widać w porównaniu z Fabryką uproszczoną czy Fabryką statyczną.
1.3.2. Diagram UML¶

1.3.3. Kod¶
Ten kod znajdziesz również na GitHub.
Logger.php
1 2 3 4 5 6 7 8 9 10 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
interface Logger
{
public function log(string $message);
}
|
StdoutLogger.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLogger implements Logger
{
public function log(string $message)
{
echo $message;
}
}
|
FileLogger.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
class FileLogger implements Logger
{
public function __construct(private string $filePath)
{
}
public function log(string $message)
{
file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
}
}
|
LoggerFactory.php
1 2 3 4 5 6 7 8 9 10 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
interface LoggerFactory
{
public function createLogger(): Logger;
}
|
StdoutLoggerFactory.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLoggerFactory implements LoggerFactory
{
public function createLogger(): Logger
{
return new StdoutLogger();
}
}
|
FileLoggerFactory.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
declare(strict_types=1);
namespace DesignPatterns\Creational\FactoryMethod;
class FileLoggerFactory implements LoggerFactory
{
public function __construct(private string $filePath)
{
}
public function createLogger(): Logger
{
return new FileLogger($this->filePath);
}
}
|
1.3.4. Testy¶
Tests/FactoryMethodTest.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 | <?php
declare(strict_types=1);
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);
}
}
|