Статическая Фабрика (англ. Static Factory)
Разница между этим шаблоном и Простой Фабрикой заключается в том, что Статическая Фабрика использует только один
статический метод, чтобы создать все допустимые типы объектов. Этот метод, обычно, называется factory
или build
.
Пример такой же, как и с Простой Фабрикой. Только метод мы делаем статическим.
-
Burgers
-
Burger.php
<?php namespace DesignPatterns\Creational\StaticFactory\Burgers; /** * Class Burger * @package DesignPatterns\Creational\StaticFactory\Burgers */ abstract class Burger { /** * @var string */ protected $meat; /** * @var string */ protected $sauce; /** * @var string */ protected $withCheese; /** * @return string */ public function getMeat(): string { return $this->meat; } /** * @param string $meat * * @return void */ public function setMeat(string $meat) { $this->meat = $meat; } /** * @return string */ public function getSauce(): string { return $this->sauce; } /** * @param string $sauce * * @return void */ public function setSauce(string $sauce) { $this->sauce = $sauce; } /** * @return bool */ public function getWithCheese(): bool { return $this->withCheese; } /** * @param bool $withCheese * * @return void */ public function setWithCheese(bool $withCheese) { $this->withCheese = $withCheese; } }
-
Cheeseburger.php
<?php namespace DesignPatterns\Creational\StaticFactory\Burgers; /** * Class Cheeseburger * @package DesignPatterns\Creational\StaticFactory\Burgers */ class Cheeseburger extends Burger { /** * @var string */ protected $meat = 'chicken'; /** * @var string */ protected $sauce = 'mayonnaise'; /** * @var bool */ protected $withCheese = true; }
-
Hamburger.php
<?php namespace DesignPatterns\Creational\StaticFactory\Burgers; /** * Class Hamburger * @package DesignPatterns\Creational\StaticFactory\Burgers */ class Hamburger extends Burger { /** * @var string */ protected $meat = 'beef'; /** * @var string */ protected $sauce = 'ketchup'; /** * @var bool */ protected $withCheese = false; }
-
-
Chef.php
<?php namespace DesignPatterns\Creational\StaticFactory; use DesignPatterns\Creational\StaticFactory\Burgers\Burger; use DesignPatterns\Creational\StaticFactory\Burgers\Hamburger; use DesignPatterns\Creational\StaticFactory\Burgers\Cheeseburger; /** * Class Chef * @package DesignPatterns\Creational\StaticFactory */ class Chef { /** * @param string $typeBurger * * @return Burger */ public static function makeBurger(string $typeBurger): Burger { $typeBurger = strtolower($typeBurger); switch ($typeBurger) { case 'cheeseburger': return new Cheeseburger(); case 'hamburger': return new Hamburger(); default: throw new \InvalidArgumentException('Sorry. But we haven\'t this burger.'); } } }
Test case:
StaticFactoryTest.php
<?php
namespace DesignPatterns\Tests\Creational\StaticFactory;
use DesignPatterns\Creational\StaticFactory\Chef;
use InvalidArgumentException;
use PHPUnit_Framework_TestCase;
class StaticFactoryTest extends PHPUnit_Framework_TestCase
{
public function testHamburgerInstanceOfBurger()
{
$hamburger = Chef::makeBurger('hamburger');
$someHamburger = Chef::makeBurger('hamburger');
$this->assertInstanceOf('DesignPatterns\Creational\StaticFactory\Burgers\Burger', $hamburger);
$this->assertInstanceOf('DesignPatterns\Creational\StaticFactory\Burgers\Burger', $someHamburger);
$this->assertNotSame($hamburger, $someHamburger);
}
public function testCheeseburgerInstanceOfBurger()
{
$cheeseburger = Chef::makeBurger('cheeseburger');
$someCheeseburger = Chef::makeBurger('cheeseburger');
$this->assertInstanceOf('DesignPatterns\Creational\StaticFactory\Burgers\Burger', $cheeseburger);
$this->assertInstanceOf('DesignPatterns\Creational\StaticFactory\Burgers\Burger', $someCheeseburger);
$this->assertNotSame($cheeseburger, $someCheeseburger);
}
public function testException()
{
$this->expectException(InvalidArgumentException::class);
Chef::makeBurger('someNameForBurger');
}
public function testHamburgerСomposition()
{
$hamburger = Chef::makeBurger('hamburger');
$hamburgerMeat = $hamburger->getMeat();
$hamburgerSauce = $hamburger->getSauce();
$hamburgerWithCheese = $hamburger->getWithCheese();
$this->assertEquals('beef', $hamburgerMeat);
$this->assertNotEquals('chicken', $hamburgerMeat);
$this->assertEquals('ketchup', $hamburgerSauce);
$this->assertNotEquals('mayonnaise', $hamburgerSauce);
$this->assertEquals(false, $hamburgerWithCheese);
$this->assertNotEquals(true, $hamburgerWithCheese);
}
public function testCheeseburgerСomposition()
{
$cheeseburger = Chef::makeBurger('cheeseburger');
$cheeseburgerMeat = $cheeseburger->getMeat();
$cheeseburgerSauce = $cheeseburger->getSauce();
$cheeseburgerWithCheese = $cheeseburger->getWithCheese();
$this->assertEquals('chicken', $cheeseburgerMeat);
$this->assertNotEquals('beef', $cheeseburgerMeat);
$this->assertEquals('mayonnaise', $cheeseburgerSauce);
$this->assertNotEquals('ketchup', $cheeseburgerSauce);
$this->assertEquals(true, $cheeseburgerWithCheese);
$this->assertNotEquals(false, $cheeseburgerWithCheese);
}
}