static-factory Статическая Фабрика (англ. 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);
        }
    }