Este patrón del diseño del software es un patrón para optimizar los recursos, para reducir el coste espacial, y probablemente también el coste temporal de nuestros programas. El patrón Flyweight o Peso Mosca se basa en la optimización de recursos disminuyendo la cantidad de información que tiene cada objeto.
Es decir, cuando tenemos muchos objetos similares con información muy parecida, conviene desacoplar la información común y agruparla en nuevos objetos, reduciendo los originales.
Al grano, un caso de estudio en PHP
Por ejemplo, supongamos que tenemos que trabajar con muchos coches que tienen texturas. La textura es algo que se repite y puede ocupar bastante espacio en memoria. Con lo que si almacenamos los datos de cada textura en cada coche, ocuparán más memoria que si simplemente almacenamos un identificador a cada textura en cada coche.
Entonces, almacenamos las texturas en clases distintas y usamos una fábrica de texturas para obtener los datos de cada una.
Además, la fábrica puede crear la textura en memoria si todavía no lo está, y devolver los datos de la que exista creada evitando crear dos texturas iguales usando el patrón Singleton.
Un esquema posible:
Ahora supongamos por ejemplo un Main en PHP, que crea un conjunto de 100 coches con texturas random, y los devuelve al front para pintarlos en JavaScript:
<?php
class Main
{
public $cars = [];
public $textures = [];
public $textureFactory;
public function main()
{
$this->textureFactory = new TextureFactory();
for ($i = 0; $i < 100; ++$i) {
$newCar = new Car();
// Random texture foreach car..
$newCar->textureID = 'Texture'.rand(1, 3);
$cars[] = $newCar;
}
foreach ($cars as $car) {
// If not isset this texture, retrive the data from the factory..
if (!isset($this->textures[$car->textureID])) {
$this->textures[$car->textureID] = $this->textureFactory->getTexture($car->textureID)->getTextureData();
}
}
/*
* Do something with textures and cars, for instance, return them to render in the front..
*/
}
}
..esto podría ser un comienzo de fábrica de texturas:
<?php
class TextureFactory
{
/**
* Here it can receive $textureID = Texture1|Texture2|Texture3.
*/
public function getTexture($textureID): ITexture
{
// This can be made using Singletones
// for a better performance..
$texture = new $textureID();
return $texture;
}
}
..un coche que sólo almacena su posición y el identificador de su textura:
<?php
class Car
{
public $textureID;
public $x;
public $y;
}
..una interfaz para definir el contrato de funciones que tiene que tener cada textura nueva:
<?php
interface ITexture
{
public function getTextureData();
}
..y una posible implementación para cada textura:
<?php
class Texture1 implements ITexture
{
public function getTextureData()
{
/*
* Here we return the data of this texture..
*/
}
}
<?php
class Texture2 implements ITexture
{
public function getTextureData()
{
/*
* Here we return the data of this texture..
*/
}
}
<?php
class Texture3 implements ITexture
{
public function getTextureData()
{
/*
* Here we return the data of this texture..
*/
}
}