--- layout: pattern title: Flyweight folder: flyweight permalink: /patterns/flyweight/ categories: Structural tags: - Gang Of Four - Performance --- ## Intent Use sharing to support large numbers of fine-grained objects efficiently. ## Explanation Real world example > Alchemist's shop has shelves full of magic potions. Many of the potions are the same so there is > no need to create new object for each of them. Instead one object instance can represent multiple > shelf items so memory footprint remains small. In plain words > It is used to minimize memory usage or computational expenses by sharing as much as possible with > similar objects. Wikipedia says > In computer programming, flyweight is a software design pattern. A flyweight is an object that > minimizes memory use by sharing as much data as possible with other similar objects; it is a way > to use objects in large numbers when a simple repeated representation would use an unacceptable > amount of memory. **Programmatic example** Translating our alchemist shop example from above. First of all we have different potion types: ```java 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)); } } ``` Then the actual Flyweight class `PotionFactory`, which is the factory for creating potions. ```java public class PotionFactory { private final Map 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); break; case HOLY_WATER: potion = new HolyWaterPotion(); potions.put(type, potion); break; case INVISIBILITY: potion = new InvisibilityPotion(); potions.put(type, potion); break; default: break; } } return potion; } } ``` And it can be used as below: ```java var factory = new PotionFactory(); factory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=6566818) factory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=648129364) factory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=6566818) factory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=1104106489) factory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=1104106489) factory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=648129364) ``` Program output: ```java You become invisible. (Potion=6566818) You feel healed. (Potion=648129364) You become invisible. (Potion=6566818) You feel blessed. (Potion=1104106489) You feel blessed. (Potion=1104106489) You feel healed. (Potion=648129364) ``` ## Class diagram ![alt text](./etc/flyweight.urm.png "Flyweight pattern class diagram") ## Applicability The Flyweight pattern's effectiveness depends heavily on how and where it's used. Apply the Flyweight pattern when all of the following are true: * An application uses a large number of objects. * Storage costs are high because of the sheer quantity of objects. * Most object state can be made extrinsic. * Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed. * The application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects. ## Real world examples * [java.lang.Integer#valueOf(int)](http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#valueOf%28int%29) and similarly for Byte, Character and other wrapped types. ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)