PHP 工廠方法模式

2022-05-05 11:24 更新

目的

相比 簡單工廠模式(SimpleFactory)而言,工廠方法模式(Factory Method)可以通過延伸出子類,實現(xiàn)用不同的方法創(chuàng)建對象。

對于比較簡單的情況,這個抽象類可能只是一個接口。

這是一個 “真正” 的設(shè)計模式,因為它遵循了”依賴反轉(zhuǎn)原則(Dependency Inversion Principle)” 。也就是 SOLID 原則中的”D”。

這意味著工廠方法實現(xiàn)的類依賴于類的抽象,而不是具體的類。這也是 工廠方法模式 與 簡單工廠模式 和 靜態(tài)工廠模式 之間最重要的區(qū)別。

1.3.2. UML 圖

Alt FactoryMethod UML Diagram

1.3.3. 代碼

Logger.php

<?php
declare(strict_types=1);

namespace DesignPatterns\Creational\FactoryMethod;

interface Logger{
    public function log(string $message);
}

StdoutLogger.php

<?php
declare(strict_types=1);

namespace DesignPatterns\Creational\FactoryMethod;

class StdoutLogger implements Logger{
    public function log(string $message){
        echo $message;
    }
}

FileLogger.php

<?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

<?php
declare(strict_types=1);

namespace DesignPatterns\Creational\FactoryMethod;

interface LoggerFactory{
    public function createLogger(): Logger;
}

StdoutLoggerFactory.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\FactoryMethod;

class StdoutLoggerFactory implements LoggerFactory
{
    public function createLogger(): Logger
    {
        return new StdoutLogger();
    }
}

FileLoggerFactory.php

<?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);
    }
}

測試

Tests/FactoryMethodTest.php

<?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);
    }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號