2.9. Миниобект
2.9.1. Предназначение
За да сведе до минимум използването на памет, миниобект споделя възможно най-много памет с подобни обекти. Това е необходимо, когато се използва голямо количество обекти, които не се различават особено по състояние. Често срещана практика е да се задържа състояние във външни структури от данни и да се предават на миниобекта, когато е необходимо.
2.9.2. UML Диаграма

2.9.3. Код
Можете също да намерите този код в GitHub
Text.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Flyweight;
6
7/**
8 * This is the interface that all flyweights need to implement
9 */
10interface Text
11{
12 public function render(string $extrinsicState): string;
13}
Word.php
1<?php
2
3namespace DesignPatterns\Structural\Flyweight;
4
5class Word implements Text
6{
7 public function __construct(private string $name)
8 {
9 }
10
11 public function render(string $extrinsicState): string
12 {
13 return sprintf('Word %s with font %s', $this->name, $extrinsicState);
14 }
15}
Character.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Flyweight;
6
7/**
8 * Implements the flyweight interface and adds storage for intrinsic state, if any.
9 * Instances of concrete flyweights are shared by means of a factory.
10 */
11class Character implements Text
12{
13 /**
14 * Any state stored by the concrete flyweight must be independent of its context.
15 * For flyweights representing characters, this is usually the corresponding character code.
16 */
17 public function __construct(private string $name)
18 {
19 }
20
21 public function render(string $extrinsicState): string
22 {
23 // Clients supply the context-dependent information that the flyweight needs to draw itself
24 // For flyweights representing characters, extrinsic state usually contains e.g. the font.
25
26 return sprintf('Character %s with font %s', $this->name, $extrinsicState);
27 }
28}
TextFactory.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Flyweight;
6
7use Countable;
8
9/**
10 * A factory manages shared flyweights. Clients should not instantiate them directly,
11 * but let the factory take care of returning existing objects or creating new ones.
12 */
13class TextFactory implements Countable
14{
15 /**
16 * @var Text[]
17 */
18 private array $charPool = [];
19
20 public function get(string $name): Text
21 {
22 if (!isset($this->charPool[$name])) {
23 $this->charPool[$name] = $this->create($name);
24 }
25
26 return $this->charPool[$name];
27 }
28
29 private function create(string $name): Text
30 {
31 if (strlen($name) == 1) {
32 return new Character($name);
33 }
34 return new Word($name);
35 }
36
37 public function count(): int
38 {
39 return count($this->charPool);
40 }
41}
2.9.4. Тест
Tests/FlyweightTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\Flyweight\Tests;
6
7use DesignPatterns\Structural\Flyweight\TextFactory;
8use PHPUnit\Framework\TestCase;
9
10class FlyweightTest extends TestCase
11{
12 private array $characters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
13 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
14
15 private array $fonts = ['Arial', 'Times New Roman', 'Verdana', 'Helvetica'];
16
17 public function testFlyweight()
18 {
19 $factory = new TextFactory();
20
21 for ($i = 0; $i <= 10; $i++) {
22 foreach ($this->characters as $char) {
23 foreach ($this->fonts as $font) {
24 $flyweight = $factory->get($char);
25 $rendered = $flyweight->render($font);
26
27 $this->assertSame(sprintf('Character %s with font %s', $char, $font), $rendered);
28 }
29 }
30 }
31
32 foreach ($this->fonts as $word) {
33 $flyweight = $factory->get($word);
34 $rendered = $flyweight->render('foobar');
35
36 $this->assertSame(sprintf('Word %s with font foobar', $word), $rendered);
37 }
38
39 // Flyweight pattern ensures that instances are shared
40 // instead of having hundreds of thousands of individual objects
41 // there must be one instance for every char that has been reused for displaying in different fonts
42 $this->assertCount(count($this->characters) + count($this->fonts), $factory);
43 }
44}