mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-08-02 21:17:29 +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.
|
* Implements the flyweight interface and adds storage for intrinsic state, if any.
|
||||||
* Instances of concrete flyweights are shared by means of a factory.
|
* 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.
|
* 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`_
|
You can also find this code on `GitHub`_
|
||||||
|
|
||||||
FlyweightInterface.php
|
Text.php
|
||||||
|
|
||||||
.. literalinclude:: FlyweightInterface.php
|
.. literalinclude:: Text.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
CharacterFlyweight.php
|
Word.php
|
||||||
|
|
||||||
.. literalinclude:: CharacterFlyweight.php
|
.. literalinclude:: Word.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
FlyweightFactory.php
|
Character.php
|
||||||
|
|
||||||
.. literalinclude:: FlyweightFactory.php
|
.. literalinclude:: Character.php
|
||||||
|
:language: php
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
TextFactory.php
|
||||||
|
|
||||||
|
.. literalinclude:: TextFactory.php
|
||||||
:language: php
|
:language: php
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace DesignPatterns\Structural\Flyweight\Tests;
|
namespace DesignPatterns\Structural\Flyweight\Tests;
|
||||||
|
|
||||||
use DesignPatterns\Structural\Flyweight\FlyweightFactory;
|
use DesignPatterns\Structural\Flyweight\TextFactory;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class FlyweightTest extends TestCase
|
class FlyweightTest extends TestCase
|
||||||
@@ -14,20 +14,29 @@ class FlyweightTest extends TestCase
|
|||||||
|
|
||||||
public function testFlyweight()
|
public function testFlyweight()
|
||||||
{
|
{
|
||||||
$factory = new FlyweightFactory();
|
$factory = new TextFactory();
|
||||||
|
|
||||||
foreach ($this->characters as $char) {
|
for ($i = 0; $i <= 10; $i++) {
|
||||||
foreach ($this->fonts as $font) {
|
foreach ($this->characters as $char) {
|
||||||
$flyweight = $factory->get($char);
|
foreach ($this->fonts as $font) {
|
||||||
$rendered = $flyweight->render($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
|
// Flyweight pattern ensures that instances are shared
|
||||||
// instead of having hundreds of thousands of individual objects
|
// 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
|
// 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;
|
namespace DesignPatterns\Structural\Flyweight;
|
||||||
|
|
||||||
interface FlyweightInterface
|
/**
|
||||||
|
* This is the interface that all flyweights need to implement
|
||||||
|
*/
|
||||||
|
interface Text
|
||||||
{
|
{
|
||||||
public function render(string $extrinsicState): string;
|
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