# Flyweight Design Pattern in Java for Effective Memory Optimization

<div><strong>Source</strong>: <a href='https://www.tuanh.net/blog/java/flyweight-design-pattern-in-java-for-effective-memory-optimization'>Flyweight Design Pattern in Java for Effective Memory Optimization</a></div><div class="line-post"> 
 <h2 class="title-post">1. Understanding the Flyweight Design Pattern</h2> 
</div>
<div class="line-post">
  The Flyweight Pattern is a structural design pattern that focuses on minimizing memory usage by sharing common parts of objects. Instead of holding multiple instances of the same data across many objects, the Flyweight Pattern allows you to centralize these shared aspects. 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.1 Key Components of the Flyweight Pattern</h3> 
</div>
<div class="line-post"> 
 <ul> 
  <li><strong>Intrinsic State</strong>: The data that is shared across objects. It remains constant and does not vary.</li> 
  <li><strong>Extrinsic State</strong>: The data that is unique to each object instance. It is passed to the object whenever it’s needed.</li> 
  <li><strong>Flyweight Factory</strong>: This class ensures that only one instance of each intrinsic state is created and shared.</li> 
 </ul> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.2 When to Use the Flyweight Pattern</h3> 
</div>
<div class="line-post">
  Consider using the Flyweight Pattern when: 
</div>
<div class="line-post"> 
 <ul> 
  <li>There is a large number of objects that consume a significant amount of memory.</li> 
  <li>Most of these objects share identical data, and only a few attributes vary between them.</li> 
 </ul> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.3 Example Use Case: A Text Editor</h3> 
</div>
<div class="line-post">
  In a text editor, each character on the screen could be represented by a separate object. Since documents can contain thousands of characters, creating a unique object for each character could quickly consume a large amount of memory. By using the Flyweight Pattern, we can share objects representing characters with the same font style, size, and color, storing only the character's position and extrinsic state separately. 
</div>
<div class="line-post"> 
 <h2 class="title-post">2. Implementing the Flyweight Pattern in Java</h2> 
</div>
<div class="line-post">
  Below, we’ll implement a basic Flyweight Pattern to demonstrate memory optimization. 
</div>
<div class="line-post"> 
 <h3 class="sub1">2.1 Step 1: Define the Flyweight Interface</h3> 
</div>
<div class="line-post">
  The Flyweight interface declares methods that will operate on both intrinsic and extrinsic states. 
</div>
<pre class="code"><span class="keyword-css">public</span> <span class="keyword-css">interface</span> Character {<br>    <span class="keyword-css">void</span> display(<span class="keyword-css">int</span> x, <span class="keyword-css">int</span> y); // x and y are extrinsic state<br>}</pre>
<div class="line-post"> 
 <h3 class="sub1">2.2 Step 2: Create Concrete Flyweight Classes</h3> 
</div>
<div class="line-post">
  The ConcreteCharacter class implements the Character interface. It holds the intrinsic state, in this case, the char value and font information. Extrinsic data, such as x and y positions, are provided as parameters. 
</div>
<pre class="code"><span class="keyword-css">public</span> <span class="keyword-css">class</span> ConcreteCharacter <span class="keyword-css">implements</span> Character {<br>    <span class="keyword-css">private</span> <span class="keyword-css">final</span> <span class="keyword-css">char</span> symbol;<br>    <span class="keyword-css">private</span> <span class="keyword-css">final</span> String font;<br><br>    <span class="keyword-css">public</span> ConcreteCharacter(<span class="keyword-css">char</span> symbol, String font) {<br>        <span class="keyword-css">this</span>.symbol = symbol;<br>        <span class="keyword-css">this</span>.font = font;<br>    }<br><br>    @Override<br>    <span class="keyword-css">public</span> <span class="keyword-css">void</span> display(<span class="keyword-css">int</span> x, <span class="keyword-css">int</span> y) {<br>        System.out.println("Displaying character " + symbol + " at (" + x + ", " + y + ") with font " + font);<br>    }<br>}</pre>
<div class="line-post"> 
 <h3 class="sub1">2.3 Step 3: Create a Flyweight Factory</h3> 
</div>
<div class="line-post">
  The Flyweight Factory is responsible for creating and managing Flyweight objects. It stores the shared instances in a map, and if an instance with a specific intrinsic state already exists, it returns that instance instead of creating a new one. 
</div>
<pre class="code"><span class="keyword-css">import</span> java.util.HashMap;<br><span class="keyword-css">import</span> java.util.Map;<br><br><span class="keyword-css">public</span> <span class="keyword-css">class</span> CharacterFactory {<br>    <span class="keyword-css">private</span> Map&lt;String, Character&gt; characters = <span class="keyword-css">new</span> HashMap&lt;&gt;();<br><br>    <span class="keyword-css">public</span> Character getCharacter(<span class="keyword-css">char</span> symbol, String font) {<br>        String key = symbol + "-" + font;<br>        <span class="keyword-css">if</span> (!characters.containsKey(key)) {<br>            characters.put(key, <span class="keyword-css">new</span> ConcreteCharacter(symbol, font));<br>        }<br>        <span class="keyword-css">return</span> characters.get(key);<br>    }<br>}</pre>
<div class="line-post"> 
 <h3 class="sub1">2.4 Step 4: Use the Flyweight in the Client Code</h3> 
</div>
<div class="line-post">
  In the main method, we utilize the Flyweight Pattern by creating multiple character instances but sharing the same intrinsic data for characters with the same appearance. 
</div>
<pre class="code"><span class="keyword-css">public</span> <span class="keyword-css">class</span> FlyweightDemo {<br>    <span class="keyword-css">public</span> <span class="keyword-css">static</span> <span class="keyword-css">void</span> main(String[] args) {<br>        CharacterFactory factory = <span class="keyword-css">new</span> CharacterFactory();<br><br>        Character c1 = factory.getCharacter('A', "Arial");<br>        Character c2 = factory.getCharacter('A', "Arial");<br>        Character c3 = factory.getCharacter('B', "Arial");<br><br>        // Display characters at different positions<br>        c1.display(10, 20);<br>        c2.display(15, 25);<br>        c3.display(30, 40);<br><br>        System.out.println("Are c1 and c2 the same object? " + (c1 == c2)); // Should print true<br>    }<br>}</pre>
<div class="line-post"> 
 <h2 class="title-post">3. Best Practices for Using the Flyweight Pattern</h2> 
</div>
<div class="line-post"> 
 <h3 class="sub1">3.1 Keep Extrinsic Data External</h3> 
</div>
<div class="line-post">
  One of the best practices for using the Flyweight Pattern effectively is to ensure that extrinsic data is not stored within the Flyweight objects. This helps to maintain the memory savings by keeping only the essential shared data within the objects. 
</div>
<div class="line-post"> 
 <h3 class="sub1">3.2 Use the Flyweight Pattern with Caution</h3> 
</div>
<div class="line-post">
  Not all applications benefit from the Flyweight Pattern. The pattern is best suited for scenarios where there is significant data repetition. If the objects have minimal or no shared data, this pattern could lead to unnecessary complexity. 
</div>
<div class="line-post"> 
 <h3 class="sub1">3.3 Monitor and Measure Memory Consumption</h3> 
</div>
<div class="line-post">
  Always monitor memory usage to confirm that the Flyweight Pattern is indeed reducing your application’s memory footprint. Java profiling tools, like VisualVM, can help you to see whether memory usage has improved after implementing this pattern. 
</div>
<div class="line-post"> 
 <h2 class="title-post">4. Potential Issues with the Flyweight Pattern</h2> 
</div>
<div class="line-post"> 
 <h3 class="sub1">4.1 Increased Complexity</h3> 
</div>
<div class="line-post">
  The Flyweight Pattern adds a layer of complexity, especially in managing extrinsic data. In cases where the extrinsic state is extensive, managing it can become cumbersome. 
</div>
<div class="line-post"> 
 <h3 class="sub1">4.2 Limited Flexibility</h3> 
</div>
<div class="line-post">
  Once implemented, the intrinsic state within Flyweight objects cannot be easily modified. This can be limiting if you need to support frequent updates to shared data. 
</div>
<div class="line-post"> 
 <h3 class="sub1">4.3 Trade-off Between Memory and Performance</h3> 
</div>
<div class="line-post">
  While the Flyweight Pattern reduces memory usage, it can also increase the time complexity due to the additional process of looking up and managing shared instances. 
</div>
<div class="line-post"> 
 <h2 class="title-post">5. Conclusion</h2> 
</div>
<div class="line-post">
  The Flyweight Design Pattern is an effective solution for optimizing memory in Java applications. When used appropriately, it can significantly reduce the memory footprint by sharing data across similar objects. However, it’s important to consider the added complexity and potential limitations of this pattern. If you have any questions or would like further clarification, please feel free to leave a comment below! 
</div><p><strong>Read more at </strong>: <a href='https://www.tuanh.net/blog/java/flyweight-design-pattern-in-java-for-effective-memory-optimization'>Flyweight Design Pattern in Java for Effective Memory Optimization</a></p>
