task: Explanations and grammar fixes for all the GoF patterns (#1791)
* Grammatical fixes to command pattern * Update bridge pattern readme * Fixes to builder pattern grammar * Update chain of responsibility * Improvements to the composite example * Fixes to headings * Minor updates to decorator pattern * Update facade * Update factory example * Update factory method * Update flyweight * Interpreter explanation * Update iterator readme * Add explanation for mediator pattern * Grammatical fixes to memento * Grammar fixes for observer * Update explanation for the prototype pattern * Proxy pattern grammar fixes * Update singleton * Grammar fixes to state pattern * Grammar fixes for strategy * Grammar fixes, template method * Grammar fixes for visitor * Fix typo
This commit is contained in:
@ -6,7 +6,7 @@ permalink: /patterns/flyweight/
|
||||
categories: Structural
|
||||
language: en
|
||||
tags:
|
||||
- Gang Of Four
|
||||
- Gang of Four
|
||||
- Performance
|
||||
---
|
||||
|
||||
@ -16,11 +16,11 @@ Use sharing to support large numbers of fine-grained objects efficiently.
|
||||
|
||||
## Explanation
|
||||
|
||||
Real world example
|
||||
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.
|
||||
> no need to create a new object for each of them. Instead, one object instance can represent
|
||||
> multiple shelf items so the memory footprint remains small.
|
||||
|
||||
In plain words
|
||||
|
||||
@ -36,7 +36,7 @@ Wikipedia says
|
||||
|
||||
**Programmatic example**
|
||||
|
||||
Translating our alchemist shop example from above. First of all we have different potion types:
|
||||
Translating our alchemist shop example from above. First of all, we have different potion types:
|
||||
|
||||
```java
|
||||
public interface Potion {
|
||||
@ -104,27 +104,81 @@ public class PotionFactory {
|
||||
}
|
||||
```
|
||||
|
||||
And it can be used as below:
|
||||
`AlchemistShop` contains two shelves of magic potions. The potions are created using the
|
||||
aforementioned `PotionFactory`.
|
||||
|
||||
```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)
|
||||
@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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In our scenario, a brave visitor enters the alchemist shop and drinks all the potions.
|
||||
|
||||
```java
|
||||
// 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();
|
||||
```
|
||||
|
||||
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)
|
||||
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)
|
||||
```
|
||||
|
||||
## Class diagram
|
||||
@ -138,13 +192,13 @@ 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.
|
||||
* Most of the object state can be made extrinsic.
|
||||
* Many groups of objects may be replaced by relatively few shared objects once the 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
|
||||
## Known uses
|
||||
|
||||
* [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.
|
||||
|
||||
|
@ -78,12 +78,12 @@ public class AlchemistShop {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate potions.
|
||||
* Drink all the potions.
|
||||
*/
|
||||
public void enumerate() {
|
||||
LOGGER.info("Enumerating top shelf potions\n");
|
||||
public void drinkPotions() {
|
||||
LOGGER.info("Drinking top shelf potions");
|
||||
topShelf.forEach(Potion::drink);
|
||||
LOGGER.info("Enumerating bottom shelf potions\n");
|
||||
LOGGER.info("Drinking bottom shelf potions");
|
||||
bottomShelf.forEach(Potion::drink);
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,9 @@ public class App {
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// create the alchemist shop with the potions
|
||||
var alchemistShop = new AlchemistShop();
|
||||
alchemistShop.enumerate();
|
||||
// a brave visitor enters the alchemist shop and drinks all the potions
|
||||
alchemistShop.drinkPotions();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user