mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-07-30 19:50:12 +02:00
improved Flyweight
This commit is contained in:
@@ -7,7 +7,7 @@ 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
|
||||
class Character implements Text
|
||||
{
|
||||
/**
|
||||
* Any state stored by the concrete flyweight must be independent of its context.
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@@ -20,21 +20,27 @@ Code
|
||||
|
||||
You can also find this code on `GitHub`_
|
||||
|
||||
FlyweightInterface.php
|
||||
Text.php
|
||||
|
||||
.. literalinclude:: FlyweightInterface.php
|
||||
.. literalinclude:: Text.php
|
||||
:language: php
|
||||
:linenos:
|
||||
|
||||
CharacterFlyweight.php
|
||||
Word.php
|
||||
|
||||
.. literalinclude:: CharacterFlyweight.php
|
||||
.. literalinclude:: Word.php
|
||||
:language: php
|
||||
:linenos:
|
||||
|
||||
FlyweightFactory.php
|
||||
Character.php
|
||||
|
||||
.. literalinclude:: FlyweightFactory.php
|
||||
.. literalinclude:: Character.php
|
||||
:language: php
|
||||
:linenos:
|
||||
|
||||
TextFactory.php
|
||||
|
||||
.. literalinclude:: TextFactory.php
|
||||
:language: php
|
||||
:linenos:
|
||||
|
||||
|
@@ -3,7 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace DesignPatterns\Structural\Flyweight\Tests;
|
||||
|
||||
use DesignPatterns\Structural\Flyweight\FlyweightFactory;
|
||||
use DesignPatterns\Structural\Flyweight\TextFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FlyweightTest extends TestCase
|
||||
@@ -14,20 +14,29 @@ class FlyweightTest extends TestCase
|
||||
|
||||
public function testFlyweight()
|
||||
{
|
||||
$factory = new FlyweightFactory();
|
||||
$factory = new TextFactory();
|
||||
|
||||
foreach ($this->characters as $char) {
|
||||
foreach ($this->fonts as $font) {
|
||||
$flyweight = $factory->get($char);
|
||||
$rendered = $flyweight->render($font);
|
||||
for ($i = 0; $i <= 10; $i++) {
|
||||
foreach ($this->characters as $char) {
|
||||
foreach ($this->fonts as $font) {
|
||||
$flyweight = $factory->get($char);
|
||||
$rendered = $flyweight->render($font);
|
||||
|
||||
$this->assertSame(sprintf('Character %s with font %s', $char, $font), $rendered);
|
||||
$this->assertSame(sprintf('Character %s with font %s', $char, $font), $rendered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->fonts as $word) {
|
||||
$flyweight = $factory->get($word);
|
||||
$rendered = $flyweight->render('foobar');
|
||||
|
||||
$this->assertSame(sprintf('Word %s with font foobar', $word), $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);
|
||||
$this->assertCount(count($this->characters) + count($this->fonts), $factory);
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace DesignPatterns\Structural\Flyweight;
|
||||
|
||||
interface FlyweightInterface
|
||||
/**
|
||||
* This is the interface that all flyweights need to implement
|
||||
*/
|
||||
interface Text
|
||||
{
|
||||
public function render(string $extrinsicState): string;
|
||||
}
|
39
Structural/Flyweight/TextFactory.php
Normal file
39
Structural/Flyweight/TextFactory.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
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 TextFactory implements \Countable
|
||||
{
|
||||
/**
|
||||
* @var Text[]
|
||||
*/
|
||||
private $charPool = [];
|
||||
|
||||
public function get(string $name): Text
|
||||
{
|
||||
if (!isset($this->charPool[$name])) {
|
||||
$this->charPool[$name] = $this->create($name);
|
||||
}
|
||||
|
||||
return $this->charPool[$name];
|
||||
}
|
||||
|
||||
private function create(string $name): Text
|
||||
{
|
||||
if (strlen($name) == 1) {
|
||||
return new Character($name);
|
||||
} else {
|
||||
return new Word($name);
|
||||
}
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->charPool);
|
||||
}
|
||||
}
|
21
Structural/Flyweight/Word.php
Normal file
21
Structural/Flyweight/Word.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Flyweight;
|
||||
|
||||
class Word implements Text
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function render(string $font): string
|
||||
{
|
||||
return sprintf('Word %s with font %s', $this->name, $font);
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 40 KiB |
Reference in New Issue
Block a user