Flyweight pattern
The Flyweight Pattern is mainly used to reduce the number of objects created, thereby reducing memory usage and improving performance. This type of design pattern belongs to structural patterns; it provides a way to reduce the number of objects and thus improve the object structure required by the application.
The Flyweight pattern attempts to reuse existing objects of the same type; if no matching object is found, it creates a new object. We will demonstrate this pattern by drawing 20 circles distributed at different positions using 5 objects. Since there are only 5 available colors, the color attribute is used to check the existing ones.CircleObject.
summary
intent
Reduce memory consumption when creating a large number of similar objects by sharing objects.
Main problem solved
- Avoid memory overflow problems caused by creating a large number of objects.
- Improve memory usage efficiency by sharing objects.
Use Case
- When there are a large number of similar or identical objects in the system.
- The cost of creating and destroying objects is high.
- The state of objects can be externalized, that is, part of the object's state can exist independently of the object itself.
Implementation Approach
- Define the Flyweight interface: Create a flyweight interface that defines the state that can be shared.
- Create concrete Flyweight classes: A concrete class that implements this interface and contains internal state.
- Use the Flyweight factory: Create a factory class to manage the creation and reuse of flyweight objects.
Key code
- HashMap: Use a hash table to store created flyweight objects for fast retrieval.
Application example
- String objects in Java.: Strings that already exist in the string constant pool are reused.
- Database connection pool: Database connections are reused to avoid frequent creation and destruction of connections.
Advantages
- Reduce memory consumption: By sharing objects, the number of objects in memory is reduced.
- Improve Efficiency: Reduces object creation time and improves system efficiency.
Disadvantages
- Increase system complexity: It is necessary to separate internal state and external state, which increases the complexity of design and implementation.
- Thread safety issues: If external state is not handled properly, it may cause thread safety issues.
Usage suggestions
- Consider using the Flyweight Pattern when creating a large number of similar objects.
- Ensure that the internal state of flyweight objects is shared, while the external state is independent of the object.
Notes
- State separation: Clearly distinguish internal state from external state to avoid confusion.
- Flyweight factory: Use a flyweight factory to control object creation and reuse, ensuring object consistency and integrity.
Structure
The Flyweight Pattern includes the following core roles:
Flyweight Factory:
- Responsible for creating and managing flyweight objects, usually containing a pool (cache) for storing and reusing created flyweight objects.
Concrete Flyweight:
- Implements the abstract flyweight interface and contains internal state and external state. The internal state can be shared, while the external state is passed by the client.
Abstract Flyweight:
- Defines the interface for concrete flyweights and non-shared flyweights, usually including methods for setting external state.
Client:
- Uses the flyweight factory to obtain flyweight objects and operates on flyweight objects by setting external state. Clients usually do not need to care about the specific implementation of flyweight objects.
Implementation
We will create aShapeinterface and implementationShapeentity classes of the interfaceCircleThe next step is to define the factory class.ShapeFactory。
ShapeFactoryThere is aCircleofHashMap, where the key name isCircleThe color of the object. Whenever a request is received, a circle of a specific color is created.ShapeFactoryCheck itsHashMapThe circle object in the hashmap, if foundCircleobject, then return that object; otherwise, create a new object stored in the hashmap for later use, and return it to the client.
FlyWeightPatternDemoClass usageShapeFactoryTo obtainShapeobject. It willShapeFactoryPass Information (red / green / blue/ black / white), in order to obtain the color of the object it needs.
Step 1
create an interface.
Shape.java
Step 2
Create concrete classes that implement the interface.
Circle.java
Step 3
Create a factory that generates objects of entity classes based on given information.
ShapeFactory.java
Step 4
Use this factory to obtain entity class objects by passing color information.
FlyweightPatternDemo.java
Step 5
Run the program, output result:
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 :100other extensions