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