Пристосуванець (англ. 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());
}
}