PHP 工廠方法模式

2022-05-05 11:24 更新

目的

相比 簡(jiǎn)單工廠模式(SimpleFactory)而言,工廠方法模式(Factory Method)可以通過(guò)延伸出子類(lèi),實(shí)現(xiàn)用不同的方法創(chuàng)建對(duì)象。

對(duì)于比較簡(jiǎn)單的情況,這個(gè)抽象類(lèi)可能只是一個(gè)接口。

這是一個(gè) “真正” 的設(shè)計(jì)模式,因?yàn)樗裱恕币蕾?lài)反轉(zhuǎn)原則(Dependency Inversion Principle)” 。也就是 SOLID 原則中的”D”。

這意味著工廠方法實(shí)現(xiàn)的類(lèi)依賴(lài)于類(lèi)的抽象,而不是具體的類(lèi)。這也是 工廠方法模式 與 簡(jiǎ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);
    }
}

測(cè)試

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)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)