refactored Factory Method pattern

This commit is contained in:
Dominik Liebler
2018-06-15 18:18:26 +02:00
parent f6d845e59e
commit bca6af02c0
27 changed files with 201 additions and 1198 deletions

View File

@@ -1,16 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class Bicycle implements VehicleInterface
{
/**
* @var string
*/
private $color;
public function setColor(string $rgb)
{
$this->color = $rgb;
}
}

View File

@@ -1,16 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class CarFerrari implements VehicleInterface
{
/**
* @var string
*/
private $color;
public function setColor(string $rgb)
{
$this->color = $rgb;
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class CarMercedes implements VehicleInterface
{
/**
* @var string
*/
private $color;
public function setColor(string $rgb)
{
$this->color = $rgb;
}
public function addAMGTuning()
{
// do additional tuning here
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
abstract class FactoryMethod
{
const CHEAP = 'cheap';
const FAST = 'fast';
abstract protected function createVehicle(string $type): VehicleInterface;
public function create(string $type): VehicleInterface
{
$obj = $this->createVehicle($type);
$obj->setColor('black');
return $obj;
}
}

View File

@@ -0,0 +1,21 @@
<?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);
}
}

View File

@@ -0,0 +1,21 @@
<?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);
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class GermanFactory extends FactoryMethod
{
protected function createVehicle(string $type): VehicleInterface
{
switch ($type) {
case parent::CHEAP:
return new Bicycle();
case parent::FAST:
$carMercedes = new CarMercedes();
// we can specialize the way we want some concrete Vehicle since we know the class
$carMercedes->addAMGTuning();
return $carMercedes;
default:
throw new \InvalidArgumentException("$type is not a valid vehicle");
}
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class ItalianFactory extends FactoryMethod
{
protected function createVehicle(string $type): VehicleInterface
{
switch ($type) {
case parent::CHEAP:
return new Bicycle();
case parent::FAST:
return new CarFerrari();
default:
throw new \InvalidArgumentException("$type is not a valid vehicle");
}
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
interface Logger
{
public function log(string $message);
}

View File

@@ -0,0 +1,8 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
interface LoggerFactory
{
public function createLogger(): Logger;
}

View File

@@ -5,12 +5,12 @@ Purpose
------- -------
The good point over the SimpleFactory is you can subclass it to The good point over the SimpleFactory is you can subclass it to
implement different ways to create objects implement different ways to create objects.
For simple case, this abstract class could be just an interface For simple cases, this abstract class could be just an interface.
This pattern is a "real" Design Pattern because it achieves the This pattern is a "real" Design Pattern because it achieves the
"Dependency Inversion Principle" a.k.a the "D" in S.O.L.I.D principles. Dependency Inversion principle a.k.a the "D" in SOLID principles.
It means the FactoryMethod class depends on abstractions, not concrete It means the FactoryMethod class depends on abstractions, not concrete
classes. This is the real trick compared to SimpleFactory or classes. This is the real trick compared to SimpleFactory or
@@ -28,45 +28,39 @@ Code
You can also find this code on `GitHub`_ You can also find this code on `GitHub`_
FactoryMethod.php Logger.php
.. literalinclude:: FactoryMethod.php .. literalinclude:: Logger.php
:language: php :language: php
:linenos: :linenos:
ItalianFactory.php StdoutLogger.php
.. literalinclude:: ItalianFactory.php .. literalinclude:: StdoutLogger.php
:language: php :language: php
:linenos: :linenos:
GermanFactory.php FileLogger.php
.. literalinclude:: GermanFactory.php .. literalinclude:: FileLogger.php
:language: php :language: php
:linenos: :linenos:
VehicleInterface.php LoggerFactory.php
.. literalinclude:: VehicleInterface.php .. literalinclude:: LoggerFactory.php
:language: php :language: php
:linenos: :linenos:
CarMercedes.php StdoutLoggerFactory.php
.. literalinclude:: CarMercedes.php .. literalinclude:: StdoutLoggerFactory.php
:language: php :language: php
:linenos: :linenos:
CarFerrari.php FileLoggerFactory.php
.. literalinclude:: CarFerrari.php .. literalinclude:: FileLoggerFactory.php
:language: php
:linenos:
Bicycle.php
.. literalinclude:: Bicycle.php
:language: php :language: php
:linenos: :linenos:

View File

@@ -0,0 +1,11 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLogger implements Logger
{
public function log(string $message)
{
echo $message;
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
class StdoutLoggerFactory implements LoggerFactory
{
public function createLogger(): Logger
{
return new StdoutLogger();
}
}

View File

@@ -2,54 +2,27 @@
namespace DesignPatterns\Creational\FactoryMethod\Tests; namespace DesignPatterns\Creational\FactoryMethod\Tests;
use DesignPatterns\Creational\FactoryMethod\Bicycle; use DesignPatterns\Creational\FactoryMethod\FileLogger;
use DesignPatterns\Creational\FactoryMethod\CarFerrari; use DesignPatterns\Creational\FactoryMethod\FileLoggerFactory;
use DesignPatterns\Creational\FactoryMethod\CarMercedes; use DesignPatterns\Creational\FactoryMethod\StdoutLogger;
use DesignPatterns\Creational\FactoryMethod\FactoryMethod; use DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory;
use DesignPatterns\Creational\FactoryMethod\GermanFactory;
use DesignPatterns\Creational\FactoryMethod\ItalianFactory;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class FactoryMethodTest extends TestCase class FactoryMethodTest extends TestCase
{ {
public function testCanCreateCheapVehicleInGermany() public function testCanCreateStdoutLogging()
{ {
$factory = new GermanFactory(); $loggerFactory = new StdoutLoggerFactory();
$result = $factory->create(FactoryMethod::CHEAP); $logger = $loggerFactory->createLogger();
$this->assertInstanceOf(Bicycle::class, $result); $this->assertInstanceOf(StdoutLogger::class, $logger);
} }
public function testCanCreateFastVehicleInGermany() public function testCanCreateFileLogging()
{ {
$factory = new GermanFactory(); $loggerFactory = new FileLoggerFactory(sys_get_temp_dir());
$result = $factory->create(FactoryMethod::FAST); $logger = $loggerFactory->createLogger();
$this->assertInstanceOf(CarMercedes::class, $result); $this->assertInstanceOf(FileLogger::class, $logger);
}
public function testCanCreateCheapVehicleInItaly()
{
$factory = new ItalianFactory();
$result = $factory->create(FactoryMethod::CHEAP);
$this->assertInstanceOf(Bicycle::class, $result);
}
public function testCanCreateFastVehicleInItaly()
{
$factory = new ItalianFactory();
$result = $factory->create(FactoryMethod::FAST);
$this->assertInstanceOf(CarFerrari::class, $result);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage spaceship is not a valid vehicle
*/
public function testUnknownType()
{
(new ItalianFactory())->create('spaceship');
} }
} }

View File

@@ -1,8 +0,0 @@
<?php
namespace DesignPatterns\Creational\FactoryMethod;
interface VehicleInterface
{
public function setColor(string $rgb);
}

View File

@@ -1,51 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Diagram> <Diagram>
<ID>PHP</ID> <ID>PHP</ID>
<OriginalElement>\DesignPatterns\Creational\FactoryMethod\GermanFactory</OriginalElement> <OriginalElement>\DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory</OriginalElement>
<nodes> <nodes>
<node x="87.0" y="242.0">\DesignPatterns\Creational\FactoryMethod\FactoryMethod</node> <node x="119.25" y="0.0">\DesignPatterns\Creational\FactoryMethod\LoggerFactory</node>
<node x="164.0" y="112.0">\DesignPatterns\Creational\FactoryMethod\Bicycle</node> <node x="220.0" y="124.0">\DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory</node>
<node x="308.0" y="112.0">\DesignPatterns\Creational\FactoryMethod\CarFerrari</node> <node x="183.0" y="-160.0">\DesignPatterns\Creational\FactoryMethod\FileLogger</node>
<node x="194.0" y="365.0">\DesignPatterns\Creational\FactoryMethod\ItalianFactory</node> <node x="0.0" y="101.0">\DesignPatterns\Creational\FactoryMethod\FileLoggerFactory</node>
<node x="0.0" y="101.0">\DesignPatterns\Creational\FactoryMethod\CarMercedes</node> <node x="8.0" y="-137.0">\DesignPatterns\Creational\FactoryMethod\StdoutLogger</node>
<node x="0.0" y="365.0">\DesignPatterns\Creational\FactoryMethod\GermanFactory</node> <node x="106.75" y="-261.0">\DesignPatterns\Creational\FactoryMethod\Logger</node>
<node x="157.0" y="0.0">\DesignPatterns\Creational\FactoryMethod\VehicleInterface</node>
</nodes> </nodes>
<notes /> <notes />
<edges> <edges>
<edge source="\DesignPatterns\Creational\FactoryMethod\GermanFactory" target="\DesignPatterns\Creational\FactoryMethod\FactoryMethod"> <edge source="\DesignPatterns\Creational\FactoryMethod\StdoutLogger" target="\DesignPatterns\Creational\FactoryMethod\Logger">
<point x="0.0" y="-25.5" /> <point x="0.0" y="-25.5" />
<point x="87.0" y="340.0" /> <point x="85.5" y="-185.0" />
<point x="135.5" y="340.0" /> <point x="145.5" y="-185.0" />
<point x="-48.5" y="36.5" /> <point x="-38.75" y="25.5" />
</edge> </edge>
<edge source="\DesignPatterns\Creational\FactoryMethod\CarMercedes" target="\DesignPatterns\Creational\FactoryMethod\VehicleInterface"> <edge source="\DesignPatterns\Creational\FactoryMethod\FileLogger" target="\DesignPatterns\Creational\FactoryMethod\Logger">
<point x="0.0" y="-48.0" /> <point x="0.0" y="-48.5" />
<point x="72.0" y="76.0" /> <point x="283.0" y="-185.0" />
<point x="180.0" y="76.0" /> <point x="223.0" y="-185.0" />
<point x="-46.0" y="25.5" /> <point x="38.75" y="25.5" />
</edge> </edge>
<edge source="\DesignPatterns\Creational\FactoryMethod\Bicycle" target="\DesignPatterns\Creational\FactoryMethod\VehicleInterface"> <edge source="\DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory" target="\DesignPatterns\Creational\FactoryMethod\LoggerFactory">
<point x="0.0" y="-37.0" />
<point x="0.0" y="25.5" />
</edge>
<edge source="\DesignPatterns\Creational\FactoryMethod\ItalianFactory" target="\DesignPatterns\Creational\FactoryMethod\FactoryMethod">
<point x="0.0" y="-25.5" /> <point x="0.0" y="-25.5" />
<point x="281.0" y="340.0" /> <point x="301.5" y="76.0" />
<point x="232.5" y="340.0" /> <point x="241.5" y="76.0" />
<point x="48.5" y="36.5" /> <point x="40.75" y="25.5" />
</edge> </edge>
<edge source="\DesignPatterns\Creational\FactoryMethod\CarFerrari" target="\DesignPatterns\Creational\FactoryMethod\VehicleInterface"> <edge source="\DesignPatterns\Creational\FactoryMethod\FileLoggerFactory" target="\DesignPatterns\Creational\FactoryMethod\LoggerFactory">
<point x="0.0" y="-37.0" /> <point x="0.0" y="-48.5" />
<point x="370.0" y="76.0" /> <point x="100.0" y="76.0" />
<point x="272.0" y="76.0" /> <point x="160.0" y="76.0" />
<point x="46.0" y="25.5" /> <point x="-40.75" y="25.5" />
</edge> </edge>
</edges> </edges>
<settings layout="Hierarchic Group" zoom="1.0" x="216.0" y="208.0" /> <settings layout="Hierarchic Group" zoom="1.0" x="375.0" y="60.5" />
<SelectedNodes /> <SelectedNodes>
<node>\DesignPatterns\Creational\FactoryMethod\FileLogger</node>
<node>\DesignPatterns\Creational\FactoryMethod\StdoutLogger</node>
<node>\DesignPatterns\Creational\FactoryMethod\Logger</node>
</SelectedNodes>
<Categories> <Categories>
<Category>Fields</Category> <Category>Fields</Category>
<Category>Constants</Category>
<Category>Constructors</Category> <Category>Constructors</Category>
<Category>Methods</Category> <Category>Methods</Category>
</Categories> </Categories>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -32,7 +32,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
#: ../../Creational/FactoryMethod/README.rst:15 #: ../../Creational/FactoryMethod/README.rst:15

View File

@@ -39,10 +39,10 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Dieses Muster ist ein \"echtes\" Muster, da es das \"D\" in S.O.L.I.D. " "Dieses Muster ist ein \"echtes\" Muster, da es das \"D\" in SOLID "
"implementiert, das \"Dependency Inversion Prinzip\"." "implementiert, das Dependency Inversion Prinzip."
#: ../../Creational/FactoryMethod/README.rst:15 #: ../../Creational/FactoryMethod/README.rst:15
msgid "" msgid ""

View File

@@ -36,7 +36,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
#: ../../Creational/FactoryMethod/README.rst:15 #: ../../Creational/FactoryMethod/README.rst:15

View File

@@ -38,7 +38,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the Dependency " "This pattern is a \"real\" Design Pattern because it achieves the Dependency "
"Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Este es un patrón \"real\" de diseño porque realiza el Principio de " "Este es un patrón \"real\" de diseño porque realiza el Principio de "
"Inversión de Dependencia, también conocido como la \"D\" de los principios S." "Inversión de Dependencia, también conocido como la \"D\" de los principios S."

View File

@@ -35,7 +35,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Ten wzorzec implementuje jedną z podstawowych zasad programowania obiektowego `SOLID <https://pl.wikipedia.org/wiki/SOLID_(programowanie_obiektowe)>`_ - \"D\" - zasadę odwrócenia zależności (ang. `Dependency inversion principle`)." "Ten wzorzec implementuje jedną z podstawowych zasad programowania obiektowego `SOLID <https://pl.wikipedia.org/wiki/SOLID_(programowanie_obiektowe)>`_ - \"D\" - zasadę odwrócenia zależności (ang. `Dependency inversion principle`)."

View File

@@ -35,10 +35,10 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Este padrão é um padrão de projetos de software \"real\" já que " "Este padrão é um padrão de projetos de software \"real\" já que "
"trata o \"Princípio da inversão de dependências\" o \"D\" nos princípios S.O.L.I.D" "trata o \"Princípio da inversão de dependências\" o \"D\" nos princípios SOLID"
#: ../../Creational/FactoryMethod/README.rst:15 #: ../../Creational/FactoryMethod/README.rst:15
msgid "" msgid ""

View File

@@ -37,7 +37,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Этот паттерн является «настоящим» Шаблоном Проектирования, потому что он " "Этот паттерн является «настоящим» Шаблоном Проектирования, потому что он "
"следует «Принципу инверсии зависимостей\" ака \"D\" в `S.O.L.I.D <https://" "следует «Принципу инверсии зависимостей\" ака \"D\" в `S.O.L.I.D <https://"

View File

@@ -35,7 +35,7 @@ msgstr "Basit bir durum için ise, bu soyut sınıf (abstract class) yanlızca b
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"Bu desen \"gerçek\" bir Tasarım Deseni'dir, çünkü S.O.L.I.D ilkelerinden biri olan " "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 " "\"D\" yani \"Dependency Inversion Principle (Bağımlılık Tersinme İlkesi)\" bölümünün "

View File

@@ -34,7 +34,7 @@ msgstr ""
#: ../../Creational/FactoryMethod/README.rst:12 #: ../../Creational/FactoryMethod/README.rst:12
msgid "" msgid ""
"This pattern is a \"real\" Design Pattern because it achieves the " "This pattern is a \"real\" Design Pattern because it achieves the "
"\"Dependency Inversion Principle\" a.k.a the \"D\" in S.O.L.I.D principles." "Dependency Inversion principle a.k.a the \"D\" in SOLID principles."
msgstr "" msgstr ""
"这个模式是一个 \"真正\" 的设计模式因为它遵循了依赖反转原则Dependency Inversion Principle 众所周知这个 \"D\" 代表了真正的面向对象程序设计。" "这个模式是一个 \"真正\" 的设计模式因为它遵循了依赖反转原则Dependency Inversion Principle 众所周知这个 \"D\" 代表了真正的面向对象程序设计。"