2015-08-13 23:54:40 +02:00
---
layout: pattern
title: Flyweight
folder: flyweight
2015-08-15 18:03:05 +02:00
permalink: /patterns/flyweight/
2015-08-20 21:40:07 +02:00
categories: Structural
2016-08-20 20:49:28 +05:30
tags:
2015-09-22 18:25:56 +05:30
- Gang Of Four
2015-12-28 16:07:43 +02:00
- Performance
2015-08-13 23:54:40 +02:00
---
2016-01-03 21:14:30 +01:00
## Intent
2020-08-29 21:05:30 +03:00
Use sharing to support large numbers of fine-grained objects efficiently.
2015-08-13 23:54:40 +02:00
2017-09-06 22:31:21 +03:00
## Explanation
2020-08-29 21:05:30 +03:00
2017-09-06 22:31:21 +03:00
Real world example
2020-08-29 21:05:30 +03:00
> 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.
2017-09-06 22:31:21 +03:00
In plain words
2020-08-29 21:05:30 +03:00
> It is used to minimize memory usage or computational expenses by sharing as much as possible with
> similar objects.
2017-09-06 22:31:21 +03:00
Wikipedia says
2020-08-29 21:05:30 +03:00
> 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.
2017-09-06 22:31:21 +03:00
**Programmatic example**
2020-08-29 21:05:30 +03:00
Translating our alchemist shop example from above. First of all we have different potion types:
2017-09-06 22:31:21 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-09-06 22:31:21 +03:00
public interface Potion {
void drink();
}
2021-03-13 13:19:21 +01:00
@Slf4j
2017-09-06 22:31:21 +03:00
public class HealingPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You feel healed. (Potion={})", System.identityHashCode(this));
}
}
2021-03-13 13:19:21 +01:00
@Slf4j
2017-09-06 22:31:21 +03:00
public class HolyWaterPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You feel blessed. (Potion={})", System.identityHashCode(this));
}
}
2021-03-13 13:19:21 +01:00
@Slf4j
2017-09-06 22:31:21 +03:00
public class InvisibilityPotion implements Potion {
@Override
public void drink() {
LOGGER.info("You become invisible. (Potion={})", System.identityHashCode(this));
}
}
```
2020-08-29 21:05:30 +03:00
Then the actual Flyweight class `PotionFactory` , which is the factory for creating potions.
2017-09-06 22:31:21 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-09-06 22:31:21 +03:00
public class PotionFactory {
private final Map< PotionType , Potion > potions;
public PotionFactory() {
potions = new EnumMap< >(PotionType.class);
}
Potion createPotion(PotionType type) {
2019-12-22 18:11:19 +05:30
var potion = potions.get(type);
2017-09-06 22:31:21 +03:00
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;
}
}
```
2020-08-29 21:05:30 +03:00
And it can be used as below:
2017-09-06 22:31:21 +03:00
2018-03-28 01:35:43 -04:00
```java
2019-12-22 18:11:19 +05:30
var factory = new PotionFactory();
2017-09-06 22:31:21 +03:00
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)
```
2015-08-13 23:54:40 +02:00
2020-08-29 21:05:30 +03:00
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)
```
2019-12-07 20:01:13 +02:00
## Class diagram
2020-08-29 21:05:30 +03:00
2019-12-07 20:01:13 +02:00

2016-01-03 21:14:30 +01:00
## Applicability
2020-08-29 21:05:30 +03:00
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.
2015-08-13 23:54:40 +02:00
2016-01-03 21:14:30 +01:00
## Real world examples
2015-08-13 23:54:40 +02:00
2016-08-20 20:49:28 +05:30
* [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.
2015-09-22 18:25:56 +05:30
2016-01-03 21:14:30 +01:00
## Credits
2015-09-22 18:25:56 +05:30
2020-07-06 13:31:07 +03:00
* [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 )
2020-07-07 18:05:11 +03:00
* [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 )