5: Quinto patrón de diseño - FranzBurneo/Patrones-de-dise-o GitHub Wiki

Flyweight

Flyweight pertenece a los patrones de diseño estructural, este patrón permite colocar más objetos en la RAM disponible, esto se hace compartiendo partes comunes de estado entre varios objetos en lugar de mantener todos los datos en cada objeto. Además utiliza la estrategia de Motif GUI de reemplazar widgets pesados con dispositivos livianos.

Problema

Diseñar los objetos hasta los niveles más bajos de "granularity" del sistema proporciona una flexibilidad óptima, pero como resultado nos devuelve un muy alto precio en términos de rendimiento y uso de memoria

Usabilidad

Este patrón utiliza el uso compartido para admitir una gran cantidad de objetos de manera eficiente. Esta ventaja la hace uso los navegadores web modernos, debido a que utilizan esta técnica para cargar las mismas imágenes más de una vez. Cuando el navegador carga una página, recorre todas las imágenes de esa página. El navegador carga todas las imágenes nuevas de Internet y las coloca en el caché interno. Para las imágenes ya cargadas, se crea un objeto de Flyweight el cual tiene algunos datos únicos como la posición en la página, pero todo lo demás está referenciado al almacenado en caché.

Estructura

Los Flyweight se alamacenan en el repositorio de un Factory. El cliente no crea los Flyweights pero los solicita a Factory. Cada Flyweight no se puede sostener por sí solo. Cualquier atributo que hace imposible compartirlo debe ser proporcionado por el cliente siempre que se haga una solicitud de Flyweight. Si el contexto se presta a una "economy of scale" (el cliente puede calcular o buscar los atributos necesarios), entonces el patrón Flyweight ofrece el aplacamiento adecuado.

Los Ant, Locust y Cockroach las clases pueden ser "ligero" debido a que su estado de la instancia especígica ha sido de-encapsulated, o exterioriza, y deben ser suministrados por el cliente.

Ejemplo

Se utiliza el uso compartido para admitir una gran cantidad de objetos detallados de manera eficiente import abc

class FlyweightFactory:

Cree y administre objetos de Flyweight. Asegúrese de que los Flyweights se compartan correctamente. Cuando un cliente solicita un Flyweight, el objeto FlyweightFactory proporciona una instancia existente o crea una, si no existe ninguna.

def __init__(self):
    self._flyweights = {}

def get_flyweight(self, key):
    try:
        flyweight = self._flyweights[key]
    except KeyError:
        flyweight = ConcreteFlyweight()
        self._flyweights[key] = flyweight
    return flyweight

class Flyweight(metaclass=abc.ABCMeta):

Declaramos una interfaz a través de la cual los Flyweight puedan recibir y actuar en estado extrínseco.

def __init__(self):
    self.intrinsic_state = None

@abc.abstractmethod
def operation(self, extrinsic_state):
    pass

class ConcreteFlyweight(Flyweight):

Se implementa la interfaz Flyweight y se agrega almacenamiento para el estado intrínseco, si lo hay. Un objeto ConcreteFlyweight debe poder compartirse. Ningun estado almacenado debe ser intrínseco; es decir, debe ser independiente del contexto del objeto ConcreteFlyweight.

def operation(self, extrinsic_state):
    pass

def main():

flyweight_factory = FlyweightFactory()
concrete_flyweight = flyweight_factory.get_flyweight("key")
concrete_flyweight.operation(None)

if __name__ == "__main__":

main()

Bibliografía

https://sourcemaking.com/design_patterns/flyweight