2.9. Pyłek (Flyweight)¶
2.9.1. Przeznaczenie¶
Aby zminimalizować ilość używanej pamięci Pyłek stara się dzielić ją z innymi obiektami w maksymalnym stopniu. Jest to istotne, kiedy używamy dużej liczby obiektów, których stan niewiele się różni. Powszechną praktyką jest przechowywanie stanu w zewnętrznej strukturze danych i przekazywanie go do obiektu, kiedy jest to potrzebne.
2.9.2. Diagram UML¶

2.9.3. Kod¶
Ten kod znajdziesz również na GitHub.
FlyweightInterface.php
1 2 3 4 5 6 7 8 | <?php
namespace DesignPatterns\Structural\Flyweight;
interface FlyweightInterface
{
public function render(string $extrinsicState): string;
}
|
CharacterFlyweight.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?php
namespace DesignPatterns\Structural\Flyweight;
/**
* Implements the flyweight interface and adds storage for intrinsic state, if any.
* Instances of concrete flyweights are shared by means of a factory.
*/
class CharacterFlyweight implements FlyweightInterface
{
/**
* Any state stored by the concrete flyweight must be independent of its context.
* For flyweights representing characters, this is usually the corresponding character code.
*
* @var string
*/
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function render(string $font): string
{
// Clients supply the context-dependent information that the flyweight needs to draw itself
// For flyweights representing characters, extrinsic state usually contains e.g. the font.
return sprintf('Character %s with font %s', $this->name, $font);
}
}
|
FlyweightFactory.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php
namespace DesignPatterns\Structural\Flyweight;
/**
* A factory manages shared flyweights. Clients should not instantiate them directly,
* but let the factory take care of returning existing objects or creating new ones.
*/
class FlyweightFactory implements \Countable
{
/**
* @var CharacterFlyweight[]
*/
private $pool = [];
public function get(string $name): CharacterFlyweight
{
if (!isset($this->pool[$name])) {
$this->pool[$name] = new CharacterFlyweight($name);
}
return $this->pool[$name];
}
public function count(): int
{
return count($this->pool);
}
}
|
2.9.4. Testy¶
Tests/FlyweightTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php
namespace DesignPatterns\Structural\Flyweight\Tests;
use DesignPatterns\Structural\Flyweight\FlyweightFactory;
use PHPUnit\Framework\TestCase;
class FlyweightTest extends TestCase
{
private $characters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
private $fonts = ['Arial', 'Times New Roman', 'Verdana', 'Helvetica'];
public function testFlyweight()
{
$factory = new FlyweightFactory();
foreach ($this->characters as $char) {
foreach ($this->fonts as $font) {
$flyweight = $factory->get($char);
$rendered = $flyweight->render($font);
$this->assertEquals(sprintf('Character %s with font %s', $char, $font), $rendered);
}
}
// Flyweight pattern ensures that instances are shared
// instead of having hundreds of thousands of individual objects
// there must be one instance for every char that has been reused for displaying in different fonts
$this->assertCount(count($this->characters), $factory);
}
}
|