mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-08-01 12:40:11 +02:00
PHP7 FactoryMethod
This commit is contained in:
@@ -2,22 +2,14 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
/**
|
|
||||||
* Bicycle is a bicycle.
|
|
||||||
*/
|
|
||||||
class Bicycle implements VehicleInterface
|
class Bicycle implements VehicleInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $color;
|
private $color;
|
||||||
|
|
||||||
/**
|
public function setColor(string $rgb)
|
||||||
* Sets the color of the bicycle.
|
|
||||||
*
|
|
||||||
* @param string $rgb
|
|
||||||
*/
|
|
||||||
public function setColor($rgb)
|
|
||||||
{
|
{
|
||||||
$this->color = $rgb;
|
$this->color = $rgb;
|
||||||
}
|
}
|
||||||
|
16
Creational/FactoryMethod/CarFerrari.php
Normal file
16
Creational/FactoryMethod/CarFerrari.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
|
class CarFerrari implements VehicleInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $color;
|
||||||
|
|
||||||
|
public function setColor(string $rgb)
|
||||||
|
{
|
||||||
|
$this->color = $rgb;
|
||||||
|
}
|
||||||
|
}
|
21
Creational/FactoryMethod/CarMercedes.php
Normal file
21
Creational/FactoryMethod/CarMercedes.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?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
|
||||||
|
}
|
||||||
|
}
|
@@ -2,36 +2,17 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
/**
|
|
||||||
* class FactoryMethod.
|
|
||||||
*/
|
|
||||||
abstract class FactoryMethod
|
abstract class FactoryMethod
|
||||||
{
|
{
|
||||||
const CHEAP = 1;
|
const CHEAP = 'cheap';
|
||||||
const FAST = 2;
|
const FAST = 'fast';
|
||||||
|
|
||||||
/**
|
abstract protected function createVehicle(string $type): VehicleInterface;
|
||||||
* The children of the class must implement this method.
|
|
||||||
*
|
|
||||||
* Sometimes this method can be public to get "raw" object
|
|
||||||
*
|
|
||||||
* @param string $type a generic type
|
|
||||||
*
|
|
||||||
* @return VehicleInterface a new vehicle
|
|
||||||
*/
|
|
||||||
abstract protected function createVehicle($type);
|
|
||||||
|
|
||||||
/**
|
public function create(string $type): VehicleInterface
|
||||||
* Creates a new vehicle.
|
|
||||||
*
|
|
||||||
* @param int $type
|
|
||||||
*
|
|
||||||
* @return VehicleInterface a new vehicle
|
|
||||||
*/
|
|
||||||
public function create($type)
|
|
||||||
{
|
{
|
||||||
$obj = $this->createVehicle($type);
|
$obj = $this->createVehicle($type);
|
||||||
$obj->setColor('#f00');
|
$obj->setColor('black');
|
||||||
|
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ferrari is a italian car.
|
|
||||||
*/
|
|
||||||
class Ferrari implements VehicleInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $rgb
|
|
||||||
*/
|
|
||||||
public function setColor($rgb)
|
|
||||||
{
|
|
||||||
$this->color = $rgb;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,28 +2,19 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
/**
|
|
||||||
* GermanFactory is a vehicle factory in Germany.
|
|
||||||
*/
|
|
||||||
class GermanFactory extends FactoryMethod
|
class GermanFactory extends FactoryMethod
|
||||||
{
|
{
|
||||||
/**
|
protected function createVehicle(string $type): VehicleInterface
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function createVehicle($type)
|
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case parent::CHEAP:
|
case parent::CHEAP:
|
||||||
return new Bicycle();
|
return new Bicycle();
|
||||||
break;
|
|
||||||
case parent::FAST:
|
case parent::FAST:
|
||||||
$obj = new Porsche();
|
$carMercedes = new CarMercedes();
|
||||||
// we can specialize the way we want some concrete Vehicle since
|
// we can specialize the way we want some concrete Vehicle since we know the class
|
||||||
// we know the class
|
$carMercedes->addAMGTuning();
|
||||||
$obj->addTuningAMG();
|
|
||||||
|
|
||||||
return $obj;
|
return $carMercedes;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
||||||
}
|
}
|
||||||
|
@@ -2,23 +2,15 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
/**
|
|
||||||
* ItalianFactory is vehicle factory in Italy.
|
|
||||||
*/
|
|
||||||
class ItalianFactory extends FactoryMethod
|
class ItalianFactory extends FactoryMethod
|
||||||
{
|
{
|
||||||
/**
|
protected function createVehicle(string $type): VehicleInterface
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function createVehicle($type)
|
|
||||||
{
|
{
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case parent::CHEAP:
|
case parent::CHEAP:
|
||||||
return new Bicycle();
|
return new Bicycle();
|
||||||
break;
|
|
||||||
case parent::FAST:
|
case parent::FAST:
|
||||||
return new Ferrari();
|
return new CarFerrari();
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Porsche is a german car.
|
|
||||||
*/
|
|
||||||
class Porsche implements VehicleInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $rgb
|
|
||||||
*/
|
|
||||||
public function setColor($rgb)
|
|
||||||
{
|
|
||||||
$this->color = $rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* although tuning by AMG is only offered for Mercedes Cars,
|
|
||||||
* this is a valid coding example ...
|
|
||||||
*/
|
|
||||||
public function addTuningAMG()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -52,23 +52,23 @@ VehicleInterface.php
|
|||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Porsche.php
|
CarMercedes.php
|
||||||
|
|
||||||
.. literalinclude:: Porsche.php
|
.. literalinclude:: CarMercedes.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Bicycle.php
|
CarFerrari.php
|
||||||
|
|
||||||
|
.. literalinclude:: CarFerrari.php
|
||||||
|
:language: php
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
Bicycle.php
|
||||||
|
|
||||||
.. literalinclude:: Bicycle.php
|
.. literalinclude:: Bicycle.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Ferrari.php
|
|
||||||
|
|
||||||
.. literalinclude:: Ferrari.php
|
|
||||||
:language: php
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
Test
|
Test
|
||||||
----
|
----
|
||||||
|
@@ -6,44 +6,46 @@ use DesignPatterns\Creational\FactoryMethod\FactoryMethod;
|
|||||||
use DesignPatterns\Creational\FactoryMethod\GermanFactory;
|
use DesignPatterns\Creational\FactoryMethod\GermanFactory;
|
||||||
use DesignPatterns\Creational\FactoryMethod\ItalianFactory;
|
use DesignPatterns\Creational\FactoryMethod\ItalianFactory;
|
||||||
|
|
||||||
/**
|
|
||||||
* FactoryMethodTest tests the factory method pattern.
|
|
||||||
*/
|
|
||||||
class FactoryMethodTest extends \PHPUnit_Framework_TestCase
|
class FactoryMethodTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
protected $type = array(
|
public function testCanCreateCheapVehicleInGermany()
|
||||||
FactoryMethod::CHEAP,
|
|
||||||
FactoryMethod::FAST,
|
|
||||||
);
|
|
||||||
|
|
||||||
public function getShop()
|
|
||||||
{
|
{
|
||||||
return array(
|
$factory = new GermanFactory();
|
||||||
array(new GermanFactory()),
|
$result = $factory->create(FactoryMethod::CHEAP);
|
||||||
array(new ItalianFactory()),
|
|
||||||
);
|
$this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\Bicycle', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanCreateFastVehicleInGermany()
|
||||||
|
{
|
||||||
|
$factory = new GermanFactory();
|
||||||
|
$result = $factory->create(FactoryMethod::FAST);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\CarMercedes', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanCreateCheapVehicleInItaly()
|
||||||
|
{
|
||||||
|
$factory = new ItalianFactory();
|
||||||
|
$result = $factory->create(FactoryMethod::CHEAP);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\Bicycle', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanCreateFastVehicleInItaly()
|
||||||
|
{
|
||||||
|
$factory = new ItalianFactory();
|
||||||
|
$result = $factory->create(FactoryMethod::FAST);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\CarFerrari', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getShop
|
|
||||||
*/
|
|
||||||
public function testCreation(FactoryMethod $shop)
|
|
||||||
{
|
|
||||||
// this test method acts as a client for the factory. We don't care
|
|
||||||
// about the factory, all we know is it can produce vehicle
|
|
||||||
foreach ($this->type as $oneType) {
|
|
||||||
$vehicle = $shop->create($oneType);
|
|
||||||
$this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\VehicleInterface', $vehicle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getShop
|
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
* @expectedExceptionMessage spaceship is not a valid vehicle
|
* @expectedExceptionMessage spaceship is not a valid vehicle
|
||||||
*/
|
*/
|
||||||
public function testUnknownType(FactoryMethod $shop)
|
public function testUnknownType()
|
||||||
{
|
{
|
||||||
$shop->create('spaceship');
|
(new ItalianFactory())->create('spaceship');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,15 +2,7 @@
|
|||||||
|
|
||||||
namespace DesignPatterns\Creational\FactoryMethod;
|
namespace DesignPatterns\Creational\FactoryMethod;
|
||||||
|
|
||||||
/**
|
|
||||||
* VehicleInterface is a contract for a vehicle.
|
|
||||||
*/
|
|
||||||
interface VehicleInterface
|
interface VehicleInterface
|
||||||
{
|
{
|
||||||
/**
|
public function setColor(string $rgb);
|
||||||
* sets the color of the vehicle.
|
|
||||||
*
|
|
||||||
* @param string $rgb
|
|
||||||
*/
|
|
||||||
public function setColor($rgb);
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user