Skip to content

Commit 3b1f82a

Browse files
committed
Update flyweight
1 parent 6feca5b commit 3b1f82a

File tree

4 files changed

+85
-29
lines changed

4 files changed

+85
-29
lines changed

factory-method/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ categories: Creational
77
language: en
88
tags:
99
- Extensibility
10-
- Gang Of Four
10+
- Gang of Four
1111
---
1212

1313
## Also known as

flyweight/README.md

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ permalink: /patterns/flyweight/
66
categories: Structural
77
language: en
88
tags:
9-
- Gang Of Four
9+
- Gang of Four
1010
- Performance
1111
---
1212

@@ -16,11 +16,11 @@ Use sharing to support large numbers of fine-grained objects efficiently.
1616

1717
## Explanation
1818

19-
Real world example
19+
Real-world example
2020

2121
> Alchemist's shop has shelves full of magic potions. Many of the potions are the same so there is
22-
> no need to create new object for each of them. Instead one object instance can represent multiple
23-
> shelf items so memory footprint remains small.
22+
> no need to create a new object for each of them. Instead, one object instance can represent
23+
> multiple shelf items so the memory footprint remains small.
2424
2525
In plain words
2626

@@ -36,7 +36,7 @@ Wikipedia says
3636
3737
**Programmatic example**
3838

39-
Translating our alchemist shop example from above. First of all we have different potion types:
39+
Translating our alchemist shop example from above. First of all, we have different potion types:
4040

4141
```java
4242
public interface Potion {
@@ -104,27 +104,81 @@ public class PotionFactory {
104104
}
105105
```
106106

107-
And it can be used as below:
107+
`AlchemistShop` contains two shelves of magic potions. The potions are created using the
108+
aforementioned `PotionFactory`.
108109

109110
```java
110-
var factory = new PotionFactory();
111-
factory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=6566818)
112-
factory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=648129364)
113-
factory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=6566818)
114-
factory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=1104106489)
115-
factory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=1104106489)
116-
factory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=648129364)
111+
@Slf4j
112+
public class AlchemistShop {
113+
114+
private final List<Potion> topShelf;
115+
private final List<Potion> bottomShelf;
116+
117+
public AlchemistShop() {
118+
var factory = new PotionFactory();
119+
topShelf = List.of(
120+
factory.createPotion(PotionType.INVISIBILITY),
121+
factory.createPotion(PotionType.INVISIBILITY),
122+
factory.createPotion(PotionType.STRENGTH),
123+
factory.createPotion(PotionType.HEALING),
124+
factory.createPotion(PotionType.INVISIBILITY),
125+
factory.createPotion(PotionType.STRENGTH),
126+
factory.createPotion(PotionType.HEALING),
127+
factory.createPotion(PotionType.HEALING)
128+
);
129+
bottomShelf = List.of(
130+
factory.createPotion(PotionType.POISON),
131+
factory.createPotion(PotionType.POISON),
132+
factory.createPotion(PotionType.POISON),
133+
factory.createPotion(PotionType.HOLY_WATER),
134+
factory.createPotion(PotionType.HOLY_WATER)
135+
);
136+
}
137+
138+
public final List<Potion> getTopShelf() {
139+
return List.copyOf(this.topShelf);
140+
}
141+
142+
public final List<Potion> getBottomShelf() {
143+
return List.copyOf(this.bottomShelf);
144+
}
145+
146+
public void drinkPotions() {
147+
LOGGER.info("Drinking top shelf potions\n");
148+
topShelf.forEach(Potion::drink);
149+
LOGGER.info("Drinking bottom shelf potions\n");
150+
bottomShelf.forEach(Potion::drink);
151+
}
152+
}
153+
```
154+
155+
In our scenario, a brave visitor enters the alchemist shop and drinks all the potions.
156+
157+
```java
158+
// create the alchemist shop with the potions
159+
var alchemistShop = new AlchemistShop();
160+
// a brave visitor enters the alchemist shop and drinks all the potions
161+
alchemistShop.drinkPotions();
117162
```
118163

119164
Program output:
120165

121166
```java
122-
You become invisible. (Potion=6566818)
123-
You feel healed. (Potion=648129364)
124-
You become invisible. (Potion=6566818)
125-
You feel blessed. (Potion=1104106489)
126-
You feel blessed. (Potion=1104106489)
127-
You feel healed. (Potion=648129364)
167+
Drinking top shelf potions
168+
You become invisible. (Potion=1509514333)
169+
You become invisible. (Potion=1509514333)
170+
You feel strong. (Potion=739498517)
171+
You feel healed. (Potion=125130493)
172+
You become invisible. (Potion=1509514333)
173+
You feel strong. (Potion=739498517)
174+
You feel healed. (Potion=125130493)
175+
You feel healed. (Potion=125130493)
176+
Drinking bottom shelf potions
177+
Urgh! This is poisonous. (Potion=166239592)
178+
Urgh! This is poisonous. (Potion=166239592)
179+
Urgh! This is poisonous. (Potion=166239592)
180+
You feel blessed. (Potion=991505714)
181+
You feel blessed. (Potion=991505714)
128182
```
129183

130184
## Class diagram
@@ -138,13 +192,13 @@ Flyweight pattern when all of the following are true:
138192

139193
* An application uses a large number of objects.
140194
* Storage costs are high because of the sheer quantity of objects.
141-
* Most object state can be made extrinsic.
142-
* Many groups of objects may be replaced by relatively few shared objects once extrinsic state is
143-
removed.
195+
* Most of the object state can be made extrinsic.
196+
* Many groups of objects may be replaced by relatively few shared objects once the extrinsic state
197+
is removed.
144198
* The application doesn't depend on object identity. Since flyweight objects may be shared, identity
145199
tests will return true for conceptually distinct objects.
146200

147-
## Real world examples
201+
## Known uses
148202

149203
* [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.
150204

flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ public final List<Potion> getBottomShelf() {
7878
}
7979

8080
/**
81-
* Enumerate potions.
81+
* Drink all the potions.
8282
*/
83-
public void enumerate() {
84-
LOGGER.info("Enumerating top shelf potions\n");
83+
public void drinkPotions() {
84+
LOGGER.info("Drinking top shelf potions");
8585
topShelf.forEach(Potion::drink);
86-
LOGGER.info("Enumerating bottom shelf potions\n");
86+
LOGGER.info("Drinking bottom shelf potions");
8787
bottomShelf.forEach(Potion::drink);
8888
}
8989
}

flyweight/src/main/java/com/iluwatar/flyweight/App.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public class App {
4343
* @param args command line args
4444
*/
4545
public static void main(String[] args) {
46+
// create the alchemist shop with the potions
4647
var alchemistShop = new AlchemistShop();
47-
alchemistShop.enumerate();
48+
// a brave visitor enters the alchemist shop and drinks all the potions
49+
alchemistShop.drinkPotions();
4850
}
4951
}

0 commit comments

Comments
 (0)