1.3. Factory Method

1.3.1. Amaç

Fabrika Yöntemi’nin güzel tarafı Simple Factory aksine, kendisini alt neslerle genişleterek (subclassing), bu yolla farklı biçimlerde nesne oluşturabilmeye olanak sağlamasıdır.

For simple cases, this abstract class could be just an interface.

Bu desen “gerçek” bir Tasarım Deseni’dir, çünkü S.O.L.I.D ilkelerinden biri olan “D” yani “Dependency Inversion Principle (Bağımlılık Tersinme İlkesi)” bölümünün sorumluluğunu yerine getirir.

Bu, Factory Method sınıfının somut sınıflara değil soyutlamalara (abstraction) dayandığı anlamına gelir. İşte işin püf noktası da, Simple Factory veya Static Factory ile karşılaştırıldığında budur.

1.3.2. UML Diyagramı

Alt FactoryMethod UML Diyagramı

1.3.3. Kod

Bu kodu Github üzerinde de bulabilirsiniz.

Logger.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7interface Logger
 8{
 9    public function log(string $message);
10}

StdoutLogger.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7class StdoutLogger implements Logger
 8{
 9    public function log(string $message)
10    {
11        echo $message;
12    }
13}

FileLogger.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7class FileLogger implements Logger
 8{
 9    public function __construct(private string $filePath)
10    {
11    }
12
13    public function log(string $message)
14    {
15        file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
16    }
17}

LoggerFactory.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7interface LoggerFactory
 8{
 9    public function createLogger(): Logger;
10}

StdoutLoggerFactory.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7class StdoutLoggerFactory implements LoggerFactory
 8{
 9    public function createLogger(): Logger
10    {
11        return new StdoutLogger();
12    }
13}

FileLoggerFactory.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod;
 6
 7class FileLoggerFactory implements LoggerFactory
 8{
 9    public function __construct(private string $filePath)
10    {
11    }
12
13    public function createLogger(): Logger
14    {
15        return new FileLogger($this->filePath);
16    }
17}

1.3.4. Test

Tests/FactoryMethodTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\FactoryMethod\Tests;
 6
 7use DesignPatterns\Creational\FactoryMethod\FileLogger;
 8use DesignPatterns\Creational\FactoryMethod\FileLoggerFactory;
 9use DesignPatterns\Creational\FactoryMethod\StdoutLogger;
10use DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory;
11use PHPUnit\Framework\TestCase;
12
13class FactoryMethodTest extends TestCase
14{
15    public function testCanCreateStdoutLogging()
16    {
17        $loggerFactory = new StdoutLoggerFactory();
18        $logger = $loggerFactory->createLogger();
19
20        $this->assertInstanceOf(StdoutLogger::class, $logger);
21    }
22
23    public function testCanCreateFileLogging()
24    {
25        $loggerFactory = new FileLoggerFactory(sys_get_temp_dir());
26        $logger = $loggerFactory->createLogger();
27
28        $this->assertInstanceOf(FileLogger::class, $logger);
29    }
30}