* Typo corrections * bridge pattern translated to spanish * builder pattern translated to spanish * context-object pattern translated to spanish * converter pattern translated to spanish * dependency injection pattern translated to spanish * factory pattern translated to spanish * factory-kit pattern translated to spanish * factory-method pattern translated to spanish * monostate pattern translated to spanish * multiton pattern translated to spanish * object mother pattern translated to spanish * object pool pattern translated to spanish * property pattern translated to spanish * prototype pattern translated to spanish * registry pattern translated to spanish * step builder pattern translated to spanish * value object pattern translated to spanish * typo corrections and resources urls refactor * grammar corrections * Add image to each pattern * translate all structural patterns to Spanish --------- Co-authored-by: luismateoh <luismateohm@gmail.com> Co-authored-by: luis.hincapie <luis.hincapie@blankfactor.com>
title, category, language, tag
| title | category | language | tag | ||
|---|---|---|---|---|---|
| Flyweight | Structural | es |
|
Propósito
Utilice la compartición para dar soporte a un gran número de objetos finos de forma eficiente.
Explicación
Un ejemplo real
La tienda del alquimista tiene estanterías llenas de pociones mágicas. Muchas de las pociones son las mismas, por lo que no es necesario crear un nuevo objeto para cada una de ellas. En su lugar, una instancia de objeto puede representar múltiples elementos de la estantería para que la huella de memoria siga siendo pequeña.
En pocas palabras
Se utiliza para minimizar el uso de memoria o los gastos computacionales compartiendo todo lo posible con objetos similares.
Wikipedia dice
En programación informática, flyweight es un patrón de diseño de software. Un flyweight es un objeto que minimiza el uso de memoria compartiendo tantos datos como sea posible con otros objetos similares; es una forma de utilizar objetos en grandes cantidades cuando una simple representación repetida utilizaría una cantidad inaceptable de memoria.
Ejemplo programático
Traduciendo nuestro ejemplo de la tienda de alquimia de arriba. En primer lugar, tenemos diferentes tipos de
pociones Potion: HealingPotion, HolyWaterPotion e InvisibilityPotion:
public interface Potion {
void drink();
}
@Slf4j
public class HealingPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You feel healed. (Potion={})", System.identityHashCode(this));
}
}
@Slf4j
public class HolyWaterPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You feel blessed. (Potion={})", System.identityHashCode(this));
}
}
@Slf4j
public class InvisibilityPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You become invisible. (Potion={})", System.identityHashCode(this));
}
}
Luego la clase Flyweight PotionFactory, que es la fábrica para crear pociones.
public class PotionFactory {
private final Map<PotionType, Potion> potions;
public PotionFactory() {
potions = new EnumMap<>(PotionType.class);
}
Potion createPotion(PotionType type) {
var potion = potions.get(type);
if (potion == null) {
switch (type) {
case HEALING -> {
potion = new HealingPotion();
potions.put(type, potion);
}
case HOLY_WATER -> {
potion = new HolyWaterPotion();
potions.put(type, potion);
}
case INVISIBILITY -> {
potion = new InvisibilityPotion();
potions.put(type, potion);
}
default -> {
}
}
}
return potion;
}
}
AlchemistShop contiene dos estantes de pociones mágicas. Las pociones se crean utilizando la antes
mencionada PotionFactory.
@Slf4j
public class AlchemistShop {
private final List<Potion> topShelf;
private final List<Potion> bottomShelf;
public AlchemistShop() {
var factory = new PotionFactory();
topShelf = List.of(
factory.createPotion(PotionType.INVISIBILITY),
factory.createPotion(PotionType.INVISIBILITY),
factory.createPotion(PotionType.STRENGTH),
factory.createPotion(PotionType.HEALING),
factory.createPotion(PotionType.INVISIBILITY),
factory.createPotion(PotionType.STRENGTH),
factory.createPotion(PotionType.HEALING),
factory.createPotion(PotionType.HEALING)
);
bottomShelf = List.of(
factory.createPotion(PotionType.POISON),
factory.createPotion(PotionType.POISON),
factory.createPotion(PotionType.POISON),
factory.createPotion(PotionType.HOLY_WATER),
factory.createPotion(PotionType.HOLY_WATER)
);
}
public final List<Potion> getTopShelf() {
return List.copyOf(this.topShelf);
}
public final List<Potion> getBottomShelf() {
return List.copyOf(this.bottomShelf);
}
public void drinkPotions() {
LOGGER.info("Drinking top shelf potions\n");
topShelf.forEach(Potion::drink);
LOGGER.info("Drinking bottom shelf potions\n");
bottomShelf.forEach(Potion::drink);
}
}
En nuestro escenario, un valiente visitante entra en la tienda del alquimista y se bebe todas las pociones.
// create the alchemist shop with the potions
var alchemistShop = new AlchemistShop();
// a brave visitor enters the alchemist shop and drinks all the potions
alchemistShop.drinkPotions();
Salida del programa:
Drinking top shelf potions
You become invisible. (Potion=1509514333)
You become invisible. (Potion=1509514333)
You feel strong. (Potion=739498517)
You feel healed. (Potion=125130493)
You become invisible. (Potion=1509514333)
You feel strong. (Potion=739498517)
You feel healed. (Potion=125130493)
You feel healed. (Potion=125130493)
Drinking bottom shelf potions
Urgh! This is poisonous. (Potion=166239592)
Urgh! This is poisonous. (Potion=166239592)
Urgh! This is poisonous. (Potion=166239592)
You feel blessed. (Potion=991505714)
You feel blessed. (Potion=991505714)
Diagrama de clases
Aplicabilidad
La eficacia del patrón Flyweight depende en gran medida de cómo y dónde se utilice. Aplique el patrón Flyweight cuando se cumplan todas las condiciones siguientes:
- Una aplicación utiliza un gran número de objetos.
- Los costes de almacenamiento son altos debido a la gran cantidad de objetos.
- La mayor parte del estado de los objetos puede hacerse extrínseco.
- Muchos grupos de objetos pueden ser reemplazados por relativamente pocos objetos compartidos una vez que el estado extrínseco extrínseco.
- La aplicación no depende de la identidad de los objetos. Dado que los objetos flyweight pueden ser compartidos, las pruebas de identidad devolverán verdadero para objetos conceptualmente distintos.
Usos conocidos
- java.lang.Integer#valueOf(int) y de forma similar para Byte, Carácter y otros tipos envueltos (Wrappers).
