mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-05-23 23:09:43 +02:00
Merge branch 'factories-factories-everywhere'
This commit is contained in:
commit
5f457c2701
@ -1,42 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns;
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
/**
|
||||
* Abstract Factory pattern
|
||||
*
|
||||
* Purpose:
|
||||
* to create series of related or dependant objects without specifying their concrete classes,
|
||||
* usually the created classes all implement the same interface
|
||||
*
|
||||
* Examples:
|
||||
* - A Factory to create media in a CMS: classes would be text, audio, video, picture
|
||||
* - SQL Factory (types are all strings with SQL, but they vary in detail (tables, fields, etc.))
|
||||
* - Zend Framework: Zend_Form::createElement() creates form elements, but you could also call new T
|
||||
* TextElement() instead
|
||||
* - an abstract factory to create various exceptions (e.g. Doctrine2 uses this method)
|
||||
*
|
||||
* usually the created classes all implement the same interface. The client of the abstract
|
||||
* factory does not care about how these objects are created, he just knows they goes together.
|
||||
*
|
||||
* Sometimes also known as "Kit" in a GUI libraries.
|
||||
*
|
||||
* This design pattern implements the Dependency Inversion Principle since
|
||||
* it is the concrete subclass which creates concrete components.
|
||||
*
|
||||
* In this case, the abstract factory is a contract for creating some components
|
||||
* for the web. There are two components : Text and Picture. There is two ways
|
||||
* of rendering : HTML or JSON.
|
||||
*
|
||||
* Therefore 4 concretes classes, but the client just need to know this contract
|
||||
* to build a correct http response (for a html page or for an ajax request)
|
||||
*/
|
||||
abstract class AbstractFactory
|
||||
{
|
||||
/**
|
||||
* @static
|
||||
* Creates a text component
|
||||
*
|
||||
* @param string $content
|
||||
* @return AbstractFactory\Text
|
||||
* @return Text
|
||||
*/
|
||||
public static function createText($content)
|
||||
{
|
||||
return new AbstractFactory\Text($content);
|
||||
}
|
||||
abstract public function createText($content);
|
||||
|
||||
/**
|
||||
* @static
|
||||
* Createss a picture component
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
* @return AbstractFactory\Picture
|
||||
* @return Picture
|
||||
*/
|
||||
public static function createPicture($path, $name = '')
|
||||
{
|
||||
return new AbstractFactory\Picture($path, $name);
|
||||
}
|
||||
abstract public function createPicture($path, $name = '');
|
||||
}
|
||||
|
23
AbstractFactory/Html/Picture.php
Normal file
23
AbstractFactory/Html/Picture.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory\Html;
|
||||
|
||||
use DesignPatterns\AbstractFactory\Picture as BasePicture;
|
||||
|
||||
/**
|
||||
* Picture is a concrete image for HTML rendering
|
||||
*/
|
||||
class Picture extends BasePicture
|
||||
{
|
||||
|
||||
// some crude rendering from HTML output
|
||||
public function render()
|
||||
{
|
||||
return sprintf('<img src="%s" title="$s"/>', $this->_path, $this->_name);
|
||||
}
|
||||
|
||||
}
|
22
AbstractFactory/Html/Text.php
Normal file
22
AbstractFactory/Html/Text.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory\Html;
|
||||
|
||||
use DesignPatterns\AbstractFactory\Text as BaseText;
|
||||
|
||||
/**
|
||||
* Text is a concrete text for HTML rendering
|
||||
*/
|
||||
class Text extends BaseText
|
||||
{
|
||||
|
||||
public function render()
|
||||
{
|
||||
return "<div>" . htmlspecialchars($this->_text) . '</div>';
|
||||
}
|
||||
|
||||
}
|
25
AbstractFactory/HtmlFactory.php
Normal file
25
AbstractFactory/HtmlFactory.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
/**
|
||||
* HtmlFactory is a concrete factory for HTML component
|
||||
*/
|
||||
class HtmlFactory extends AbstractFactory
|
||||
{
|
||||
|
||||
public function createPicture($path, $name = '')
|
||||
{
|
||||
return new Html\Picture($path, $name);
|
||||
}
|
||||
|
||||
public function createText($content)
|
||||
{
|
||||
return new Html\Text($content);
|
||||
}
|
||||
|
||||
}
|
23
AbstractFactory/Json/Picture.php
Normal file
23
AbstractFactory/Json/Picture.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory\Json;
|
||||
|
||||
use DesignPatterns\AbstractFactory\Picture as BasePicture;
|
||||
|
||||
/**
|
||||
* Picture is a concrete image for JSON rendering
|
||||
*/
|
||||
class Picture extends BasePicture
|
||||
{
|
||||
|
||||
// some crude rendering from JSON output
|
||||
public function render()
|
||||
{
|
||||
return json_encode(array('title' => $this->_name, 'path' => $this->_path));
|
||||
}
|
||||
|
||||
}
|
22
AbstractFactory/Json/Text.php
Normal file
22
AbstractFactory/Json/Text.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory\Json;
|
||||
|
||||
use DesignPatterns\AbstractFactory\Text as BaseText;
|
||||
|
||||
/**
|
||||
* Text is a text component with a JSON rendering
|
||||
*/
|
||||
class Text extends BaseText
|
||||
{
|
||||
|
||||
public function render()
|
||||
{
|
||||
return json_encode(array('content' => $this->_text));
|
||||
}
|
||||
|
||||
}
|
26
AbstractFactory/JsonFactory.php
Normal file
26
AbstractFactory/JsonFactory.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
/**
|
||||
* JsonFactory is a factory for creating a family of JSON component
|
||||
* (example for ajax)
|
||||
*/
|
||||
class JsonFactory extends AbstractFactory
|
||||
{
|
||||
|
||||
public function createPicture($path, $name = '')
|
||||
{
|
||||
return new Json\Picture($path, $name);
|
||||
}
|
||||
|
||||
public function createText($content)
|
||||
{
|
||||
return new Json\Text($content);
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,12 @@
|
||||
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
/**
|
||||
* This contract is not part of the pattern, in general case, each component
|
||||
* are not related
|
||||
*/
|
||||
interface Media
|
||||
{
|
||||
|
||||
function render();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
class Picture implements Media
|
||||
abstract class Picture implements Media
|
||||
{
|
||||
protected $_path;
|
||||
protected $_name;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace DesignPatterns\AbstractFactory;
|
||||
|
||||
class Text implements Media
|
||||
abstract class Text implements Media
|
||||
{
|
||||
/**
|
||||
*
|
||||
|
20
FactoryMethod/Bicycle.php
Normal file
20
FactoryMethod/Bicycle.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* Bicycle is a bicycle
|
||||
*/
|
||||
class Bicycle implements Vehicle
|
||||
{
|
||||
|
||||
public function setColor($rgb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns;
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* Factory Method pattern
|
||||
*
|
||||
* Purpose:
|
||||
* similar to the AbstractFactory, this pattern is used to create series of related or dependant objects.
|
||||
* The difference between this and the abstract factory pattern is that the factory method pattern uses just one static
|
||||
* method to create all types of objects it can create. It is usually named "factory" or "build".
|
||||
*
|
||||
* Examples:
|
||||
* - Zend Framework: Zend_Cache_Backend or _Frontend use a factory method create cache backends or frontends
|
||||
* FactoryMethod is a factory method. The good point over the SimpleFactory
|
||||
* is you can subclass it to implement different way to create vehicle for
|
||||
* each country (see subclasses)
|
||||
*
|
||||
* For simple case, this abstract class could be just an interface
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* It means the FactoryMethod class depends on abstractions not concrete classes.
|
||||
* This is the real trick compared to SImpleFactory or StaticFactory.
|
||||
*/
|
||||
class FactoryMethod
|
||||
abstract class FactoryMethod
|
||||
{
|
||||
|
||||
const CHEAP = 1;
|
||||
const FAST = 2;
|
||||
|
||||
/**
|
||||
* the parametrized function to get create an instance
|
||||
*
|
||||
* @static
|
||||
* @return Formatter
|
||||
* 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 Vehicle a new vehicle
|
||||
*/
|
||||
public static function factory($type)
|
||||
abstract protected function createVehicle($type);
|
||||
|
||||
/**
|
||||
* Creates a new vehicle
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return Vehicle a new vehicle
|
||||
*/
|
||||
public function create($type)
|
||||
{
|
||||
$className = 'Format' . ucfirst($type);
|
||||
if ( ! class_exists($className)) {
|
||||
throw new Exception('Missing format class.');
|
||||
}
|
||||
$obj = $this->createVehicle($type);
|
||||
$obj->setColor("#f00");
|
||||
|
||||
return new $className();
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
interface Formatter
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class FormatString implements Formatter
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class FormatNumber implements Formatter
|
||||
{
|
||||
|
||||
}
|
||||
}
|
20
FactoryMethod/Ferrari.php
Normal file
20
FactoryMethod/Ferrari.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* Ferrari is a italian car
|
||||
*/
|
||||
class Ferrari implements Vehicle
|
||||
{
|
||||
|
||||
public function setColor($rgb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
39
FactoryMethod/GermanFactory.php
Normal file
39
FactoryMethod/GermanFactory.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* GermanFactory is vehicle factory in Germany
|
||||
*/
|
||||
class GermanFactory extends FactoryMethod
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function createVehicle($type)
|
||||
{
|
||||
switch ($type) {
|
||||
|
||||
case parent::CHEAP :
|
||||
return new Bicycle();
|
||||
break;
|
||||
|
||||
case parent::FAST :
|
||||
$obj = new Porsche();
|
||||
// we can specialize the way we want some concrete Vehicle since
|
||||
// we know the class
|
||||
$obj->addTuningAMG();
|
||||
return $obj;
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
FactoryMethod/ItalianFactory.php
Normal file
35
FactoryMethod/ItalianFactory.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* ItalianFactory is vehicle factory in Italy
|
||||
*/
|
||||
class ItalianFactory extends FactoryMethod
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function createVehicle($type)
|
||||
{
|
||||
switch ($type) {
|
||||
|
||||
case parent::CHEAP :
|
||||
return new Bicycle();
|
||||
break;
|
||||
|
||||
case parent::FAST :
|
||||
return new Ferrari();
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new \InvalidArgumentException("$type is not a valid vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
25
FactoryMethod/Porsche.php
Normal file
25
FactoryMethod/Porsche.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* Porsche is a german car
|
||||
*/
|
||||
class Porsche implements Vehicle
|
||||
{
|
||||
|
||||
public function setColor($rgb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function addTuningAMG()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
16
FactoryMethod/Vehicle.php
Normal file
16
FactoryMethod/Vehicle.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\FactoryMethod;
|
||||
|
||||
/**
|
||||
* Vehicle is a contract for a vehicle
|
||||
*/
|
||||
interface Vehicle
|
||||
{
|
||||
|
||||
function setColor($rgb);
|
||||
}
|
20
SimpleFactory/Bicycle.php
Normal file
20
SimpleFactory/Bicycle.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\SimpleFactory;
|
||||
|
||||
/**
|
||||
* Bicycle is a bicycle
|
||||
*/
|
||||
class Bicycle implements Vehicle
|
||||
{
|
||||
|
||||
public function driveTo($destination)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
52
SimpleFactory/ConcreteFactory.php
Normal file
52
SimpleFactory/ConcreteFactory.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\SimpleFactory;
|
||||
|
||||
/**
|
||||
* ConcreteFactory is a simple factory pattern.
|
||||
*
|
||||
* It differs from the static factory because it is NOT static and as you
|
||||
* know : static => global => evil
|
||||
*
|
||||
* Therefore, you can haZ multiple factories, differently parametrized,
|
||||
* you can subclass it and you can mock-up it.
|
||||
*/
|
||||
class ConcreteFactory
|
||||
{
|
||||
|
||||
protected $typeList;
|
||||
|
||||
/**
|
||||
* You can imagine to inject your own type list or merge with
|
||||
* the default ones...
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->typeList = array(
|
||||
'bicycle' => __NAMESPACE__ . '\Bicycle',
|
||||
'other' => __NAMESPACE__ . '\Scooter'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vehicle
|
||||
*
|
||||
* @param string $type a known type key
|
||||
* @return Vehicle a new instance of Vehicle
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function createVehicle($type)
|
||||
{
|
||||
if (!array_key_exists($type, $this->typeList)) {
|
||||
throw new \InvalidArgumentException("$type is not valid vehicle");
|
||||
}
|
||||
$className = $this->typeList[$type];
|
||||
|
||||
return new $className();
|
||||
}
|
||||
|
||||
}
|
20
SimpleFactory/Scooter.php
Normal file
20
SimpleFactory/Scooter.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\SimpleFactory;
|
||||
|
||||
/**
|
||||
* Scooter is a Scooter
|
||||
*/
|
||||
class Scooter implements Vehicle
|
||||
{
|
||||
|
||||
public function driveTo($destination)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
16
SimpleFactory/Vehicle.php
Normal file
16
SimpleFactory/Vehicle.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\SimpleFactory;
|
||||
|
||||
/**
|
||||
* Vehicle is a contract for a vehicle
|
||||
*/
|
||||
interface Vehicle
|
||||
{
|
||||
|
||||
function driveTo($destination);
|
||||
}
|
8
StaticFactory/FormatNumber.php
Normal file
8
StaticFactory/FormatNumber.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\StaticFactory;
|
||||
|
||||
class FormatNumber implements Formatter
|
||||
{
|
||||
|
||||
}
|
8
StaticFactory/FormatString.php
Normal file
8
StaticFactory/FormatString.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\StaticFactory;
|
||||
|
||||
class FormatString implements Formatter
|
||||
{
|
||||
|
||||
}
|
8
StaticFactory/Formatter.php
Normal file
8
StaticFactory/Formatter.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\StaticFactory;
|
||||
|
||||
interface Formatter
|
||||
{
|
||||
|
||||
}
|
39
StaticFactory/StaticFactory.php
Normal file
39
StaticFactory/StaticFactory.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\StaticFactory;
|
||||
|
||||
/**
|
||||
* Static Factory pattern
|
||||
*
|
||||
* Purpose:
|
||||
* similar to the AbstractFactory, this pattern is used to create series of related or dependant objects.
|
||||
* The difference between this and the abstract factory pattern is that the static factory pattern uses just one static
|
||||
* method to create all types of objects it can create. It is usually named "factory" or "build".
|
||||
*
|
||||
* Examples:
|
||||
* - Zend Framework: Zend_Cache_Backend or _Frontend use a factory method create cache backends or frontends
|
||||
*
|
||||
* Note1: Remember, static => global => evil
|
||||
* Note2: Cannot be subclassed or mock-uped or have multiple different instances
|
||||
*/
|
||||
class StaticFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* the parametrized function to get create an instance
|
||||
*
|
||||
* @static
|
||||
* @return Formatter
|
||||
*/
|
||||
public static function factory($type)
|
||||
{
|
||||
$className = __NAMESPACE__ . '\Format' . ucfirst($type);
|
||||
|
||||
if (!class_exists($className)) {
|
||||
throw new \InvalidArgumentException('Missing format class.');
|
||||
}
|
||||
|
||||
return new $className();
|
||||
}
|
||||
|
||||
}
|
50
Tests/AbstractFactory/AbstractFactoryTest.php
Normal file
50
Tests/AbstractFactory/AbstractFactoryTest.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\Tests\AbstractFactory;
|
||||
|
||||
use DesignPatterns\AbstractFactory\AbstractFactory;
|
||||
use DesignPatterns\AbstractFactory\HtmlFactory;
|
||||
use DesignPatterns\AbstractFactory\JsonFactory;
|
||||
|
||||
/**
|
||||
* AbstractFactoryTest tests concrete factories
|
||||
*/
|
||||
class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function getFactories()
|
||||
{
|
||||
return array(
|
||||
array(new JsonFactory()),
|
||||
array(new HtmlFactory())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the client of factories. Note that the client does not
|
||||
* care which factory is given to him, he can create any component he
|
||||
* wants and render how he wants.
|
||||
*
|
||||
* @dataProvider getFactories
|
||||
*/
|
||||
public function testComponentCreation(AbstractFactory $factory)
|
||||
{
|
||||
$article = array(
|
||||
$factory->createText('Lorem Ipsum'),
|
||||
$factory->createPicture('/image.jpg', 'caption'),
|
||||
$factory->createText('footnotes')
|
||||
);
|
||||
|
||||
$this->assertContainsOnly('DesignPatterns\AbstractFactory\Media', $article);
|
||||
/* this is the time to look at the Builder pattern. This pattern
|
||||
* helps you to create complex object like that article above with
|
||||
* a given Abstract Factory
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
55
Tests/FactoryMethod/FactoryMethodTest.php
Normal file
55
Tests/FactoryMethod/FactoryMethodTest.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\Tests\FactoryMethod;
|
||||
|
||||
use DesignPatterns\FactoryMethod\FactoryMethod;
|
||||
use DesignPatterns\FactoryMethod\GermanFactory;
|
||||
use DesignPatterns\FactoryMethod\ItalianFactory;
|
||||
|
||||
/**
|
||||
* FactoryMethodTest tests the factory method pattern
|
||||
*/
|
||||
class FactoryMethodTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
protected $type = array(
|
||||
FactoryMethod::CHEAP,
|
||||
FactoryMethod::FAST
|
||||
);
|
||||
|
||||
public function getShop()
|
||||
{
|
||||
return array(
|
||||
array(new GermanFactory()),
|
||||
array(new ItalianFactory())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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\FactoryMethod\Vehicle', $vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getShop
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage spaceship is not a valid vehicle
|
||||
*/
|
||||
public function testUnknownType(FactoryMethod $shop)
|
||||
{
|
||||
$shop->create('spaceship');
|
||||
}
|
||||
|
||||
}
|
51
Tests/SimpleFactory/SimpleFactoryTest.php
Normal file
51
Tests/SimpleFactory/SimpleFactoryTest.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DesignPatternPHP
|
||||
*/
|
||||
|
||||
namespace DesignPatterns\Tests\SimpleFactory;
|
||||
|
||||
use DesignPatterns\SimpleFactory\ConcreteFactory;
|
||||
|
||||
/**
|
||||
* SimpleFactoryTest tests the Simple Factory pattern
|
||||
*
|
||||
* @author flo
|
||||
*/
|
||||
class SimpleFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
protected $factory;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->factory = new ConcreteFactory();
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return array(
|
||||
array('bicycle'),
|
||||
array('other')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getType
|
||||
*/
|
||||
public function testCreation($type)
|
||||
{
|
||||
$obj = $this->factory->createVehicle($type);
|
||||
$this->assertInstanceOf('DesignPatterns\SimpleFactory\Vehicle', $obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testBadType()
|
||||
{
|
||||
$this->factory->createVehicle('car');
|
||||
}
|
||||
|
||||
}
|
31
Tests/StaticFactory/StaticFactoryTest.php
Normal file
31
Tests/StaticFactory/StaticFactoryTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Tests\StaticFactory;
|
||||
|
||||
use DesignPatterns\StaticFactory\StaticFactory;
|
||||
|
||||
/**
|
||||
* Tests for Static Factory pattern
|
||||
*
|
||||
*/
|
||||
class StaticFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function getTypeList()
|
||||
{
|
||||
return array(
|
||||
array('string'),
|
||||
array('number')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTypeList
|
||||
*/
|
||||
public function testCreation($type)
|
||||
{
|
||||
$obj = StaticFactory::factory($type);
|
||||
$this->assertInstanceOf('DesignPatterns\StaticFactory\Formatter', $obj);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user