Приспособленец (англ. Flyweight, “легковесный (элемент)”) — структурный шаблон проектирования, при котором объект,
представляющий себя как уникальный экземпляр в разных местах программы, по факту не является таковым.
Сам шаблон очень прост. В прошлом примере, мы генерировали отчет. Как и любой документ, наш отчёт мы можем разбить на компоненты. Название, контент, подпись, печать и т.д. Как мы видим многие компоненты могут повторяться, а отличие их будет только в состоянии. Каждая инициализация нового объекта использует n ресурса. И рано или поздно мы можем достичь предела. Данный шаблон даёт нам возможность использовать повторно один и тот же компонент системы, лишь меняя его состояние.
-
Factory.php
<?php namespace DesignPatterns\Structural\Flyweight; use Countable; /** * Class Factory * @package DesignPatterns\Structural\Flyweight */ class Factory implements Countable { /** * @var array */ protected $pool = []; /** * @param string $name * * @return TitleFlyweightInterface */ public function get(string $name): TitleFlyweightInterface { if (!isset($this->pool[$name])) { $this->pool[$name] = new Title($name); } return $this->pool[$name]; } /** * @return int */ public function count(): int { return count($this->pool); } }
-
Title.php
<?php namespace DesignPatterns\Structural\Flyweight; /** * Class Title * @package DesignPatterns\Structural\Flyweight */ class Title implements TitleFlyweightInterface { /** * @var string */ protected $name; /** * Contract constructor. * * @param string $name */ public function __construct(string $name) { $this->name = $name; } /** * @param string $color * * @return string */ public function print(string $color): string { return sprintf('This is %s title with color %s.', $this->name, $color); } }
-
TitleFlyweightInterface.php
<?php namespace DesignPatterns\Structural\Flyweight; /** * Interface TitleFlyweightInterface * @package DesignPatterns\Structural\Flyweight */ interface TitleFlyweightInterface { /** * @param string $color * * @return string */ public function print(string $color): string; }
Test case:
FactoryTest.php
<?php
namespace DesignPatterns\Tests\Structural\Flyweight;
use DesignPatterns\Structural\Flyweight\Factory;
use PHPUnit_Framework_TestCase;
class FlyweightTest extends PHPUnit_Framework_TestCase
{
/**
* @var Factory
*/
protected static $factory;
public static function setUpBeforeClass(): void
{
self::$factory = new Factory();
}
public function testCreateFirstTitle()
{
$firstTitle = self::$factory->get('first');
$this->assertInstanceOf('DesignPatterns\Structural\Flyweight\TitleFlyweightInterface', $firstTitle);
}
public function testCreateSecondTitle()
{
$secondTitle = self::$factory->get('second');
$this->assertInstanceOf('DesignPatterns\Structural\Flyweight\TitleFlyweightInterface', $secondTitle);
}
public function testSameFirstTitleObjects()
{
$firstTitle = self::$factory->get('first');
$sameFirstTitle = self::$factory->get('first');
$this->assertSame($firstTitle, $sameFirstTitle);
}
public function testSameSecondTitleObjects()
{
$secondTitle = self::$factory->get('second');
$sameSecondTitle = self::$factory->get('second');
$this->assertSame($secondTitle, $sameSecondTitle);
}
public function testPrint()
{
$firstTitle = self::$factory->get('first');
$this->assertEquals('This is first title with color black.', $firstTitle->print('black'));
}
public function testFactoryCount()
{
$this->assertEquals(2, self::$factory->count());
}
}