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