PHP Flyweight Pattern
A short screencast: the Flyweight pattern — share state through a cache. Let us draw a forest: one tree type for every tree, positions stored separately.
Overview
The Flyweight saves memory when objects are many and the repeating state is small. A tree type (name, color, texture) never changes — the factory returns a single TreeType for everyone. The position (x, y) is unique per tree and lives in the Tree context. Three trees are planted, but only two types are created.
UML diagram
Code
TreeType.php
class TreeType
{
public function __construct(
public string $name,
public string $color,
public string $texture,
) {
}
public function render(int $x, int $y): string
{
return "$this->name at $x, $y";
}
}
Tree.php
class Tree
{
public function __construct(
private int $x,
private int $y,
private TreeType $type,
) {
}
public function draw(): string
{
return $this->type->render($this->x, $this->y);
}
}
TreeFactory.php
class TreeFactory
{
private array $types = [];
public function place(int $x, int $y, string $name, string $color, string $texture): Tree
{
$key = "$name|$color|$texture";
if (! isset($this->types[$key])) {
$this->types[$key] = new TreeType($name, $color, $texture);
}
return new Tree($x, $y, $this->types[$key]);
}
public function count(): int
{
return count($this->types);
}
}
demo.php
require_once 'TreeType.php';
require_once 'Tree.php';
require_once 'TreeFactory.php';
$factory = new TreeFactory();
$trees[] = $factory->place(0, 0, 'Birch', 'Green', 'leaf.png');
$trees[] = $factory->place(1, 4, 'Birch', 'Green', 'leaf.png');
$trees[] = $factory->place(5, 2, 'Oak', 'DarkGreen', 'oak.png');
echo 'trees: '.count($trees).PHP_EOL;
echo 'types: '.$factory->count().PHP_EOL;
Example output
Running php demo.php shows three trees but only two types — the birches share one TreeType:
trees: 3
types: 2
Advantages
- Sharply reduces memory use with many similar objects.
- Shared (intrinsic) state is stored once and reused.
- Expensive shared data is created lazily and cached.
- The client keeps working with ordinary objects.
When to use
- When there are a huge number of objects and memory matters.
- When most state can be moved out as extrinsic state.
- When the same data repeats across many objects.
- When per-instance identity is not required.
Usage in Laravel
In Laravel the flyweight is the caching of expensive shared data: compiled Blade templates (Illuminate\View\Compilers\BladeCompiler) and loaded translations (Illuminate\Translation\Translator) are built once and reused. Config and routes produced by config:cache and route:cache are the same intrinsic state, shared across requests instead of being rebuilt.