Twenty three design patterns of JAVA -- Flyweight Pattern

Posted by twmcmahan on Sun, 06 Feb 2022 05:11:29 +0100

concept

Flyweight Pattern is mainly used to reduce the number of objects created to reduce memory consumption and improve performance. This type of design pattern belongs to structural pattern, which provides a way to reduce the number of objects and improve the object structure required by the application.

The meta pattern attempts to reuse existing homogeneous objects, and if no matching object is found, a new object is created. We will demonstrate this pattern by creating 5 objects to draw 20 circles distributed in different positions. Since there are only five colors available, the color attribute is used to check the existing Circle object.

introduce

Intention: use sharing technology to effectively support a large number of fine-grained objects.

Main solution: when there are a large number of objects, it may cause memory overflow. We abstract the common parts. If there are the same business requests, we can directly return the existing objects in memory to avoid re creation.

When to use: 1. There are a large number of objects in the system. 2. These objects consume a lot of memory. 3. Most of the states of these objects can be externalized. 4. These objects can be divided into many groups according to the intrinsic state. When the intrinsic objects are removed from the objects, each group of objects can be replaced by an object. 5. The system does not depend on the identity of these objects, which are indistinguishable.

How to solve it: use the unique identification code to judge. If there is in memory, return the object identified by the unique identification code.

Key code: use HashMap to store these objects.

Application examples: 1. String in JAVA, if any, will be returned. If not, a string will be created and saved in the string cache pool. 2. Data pool of the database.

Advantages: greatly reduce the creation of objects, reduce the memory of the system and improve the efficiency.

Disadvantages: it increases the complexity of the system and needs to separate the external state from the internal state. Moreover, the external state has inherent nature and should not change with the change of the internal state, otherwise it will cause the confusion of the system.

Usage scenario: 1. The system has a large number of similar objects. 2. Scenarios that require buffer pools.

Precautions: 1. Pay attention to the division of external state and internal state, otherwise thread safety problems may be caused. 2. These classes must have a factory object to control.

code

public interface Shape {
   void draw();
}
public class Circle implements Shape {
   private String color;
   private int x;
   private int y;
   private int radius;
 
   public Circle(String color){
      this.color = color;     
   }
 
   public void setX(int x) {
      this.x = x;
   }
 
   public void setY(int y) {
      this.y = y;
   }
 
   public void setRadius(int radius) {
      this.radius = radius;
   }
 
   @Override
   public void draw() {
      System.out.println("Circle: Draw() [Color : " + color 
         +", x : " + x +", y :" + y +", radius :" + radius);
   }
}
import java.util.HashMap;
 
public class ShapeFactory {
   private static final HashMap<String, Shape> circleMap = new HashMap<>();
 
   public static Shape getCircle(String color) {
      Circle circle = (Circle)circleMap.get(color);
 
      if(circle == null) {
         circle = new Circle(color);
         circleMap.put(color, circle);
         System.out.println("Creating circle of color : " + color);
      }
      return circle;
   }
}
public class FlyweightPatternDemo {
   private static final String colors[] = 
      { "Red", "Green", "Blue", "White", "Black" };
   public static void main(String[] args) {
 
      for(int i=0; i < 20; ++i) {
         Circle circle = 
            (Circle)ShapeFactory.getCircle(getRandomColor());
         circle.setX(getRandomX());
         circle.setY(getRandomY());
         circle.setRadius(100);
         circle.draw();
      }
   }
   private static String getRandomColor() {
      return colors[(int)(Math.random()*colors.length)];
   }
   private static int getRandomX() {
      return (int)(Math.random()*100 );
   }
   private static int getRandomY() {
      return (int)(Math.random()*100);
   }
}

Result output

Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 13, y :4, radius :100
Circle: Draw() [Color : Green, x : 21, y :21, radius :100
Circle: Draw() [Color : Blue, x : 55, y :86, radius :100
Circle: Draw() [Color : White, x : 90, y :70, radius :100
Circle: Draw() [Color : Green, x : 78, y :3, radius :100
Circle: Draw() [Color : Green, x : 64, y :89, radius :100
Circle: Draw() [Color : Blue, x : 3, y :91, radius :100
Circle: Draw() [Color : Blue, x : 62, y :82, radius :100
Circle: Draw() [Color : Green, x : 97, y :61, radius :100
Circle: Draw() [Color : Green, x : 86, y :12, radius :100
Circle: Draw() [Color : Green, x : 38, y :93, radius :100
Circle: Draw() [Color : Red, x : 76, y :82, radius :100
Circle: Draw() [Color : Blue, x : 95, y :82, radius :100

summary

In fact, it can be regarded as a pool technology, which maintains the objects to be used or possibly used in a pool in advance.

Topics: Java Design Pattern