This paper briefly introduces Adapter mode
Enjoy element mode Flyweight
summary
-
Using sharing technology to effectively support a large number of fine-grained objects.
-
It 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 for application.
-
Main solution: when there are a large number of objects, memory overflow may occur. We abstract the common parts. If there are the same business requests, we directly return the existing objects in memory to avoid re creation.
-
Type: structural design pattern
-
When to use:
- There are a large number of objects in the system.
- These objects consume a lot of memory.
- Most of the states of these objects can be externalized.
- 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.
- 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.
-
Application example:
- String in JAVA, if any, is returned. If not, a string is created and saved in the string cache pool.
- Data pool for 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 confusion of the system
-
Usage scenario: 1. The system has a large number of similar objects. 2. Scenarios that require buffer pools.
Coding
- Flyweight abstract class
The superclass or interface of all specific meta classes. Through this interface, Flyweight can accept and act on external states.
public abstract class Flyweight { //Internal state public String intrinsic; //External state protected final String extrinsic; //It is required that the meta role must accept external status public Flyweight(String extrinsic) { this.extrinsic = extrinsic; } //Define business operations public abstract void operate(int extrinsic); public String getIntrinsic() { return intrinsic; } public void setIntrinsic(String intrinsic) { this.intrinsic = intrinsic; } }
2. ConcreteFlyweight class
Inherit the Flyweight superclass or implement the Flyweight interface and add storage space for its internal state.
public class ConcreteFlyweight extends Flyweight { //Accept external status public ConcreteFlyweight(String extrinsic) { super(extrinsic); } //Logical processing according to external state @Override public void operate(int extrinsic) { System.out.println("specific Flyweight:" + extrinsic); } }
- UnsharedConcreteFlyweight class
Refers to those Flyweight subclasses that do not need to be shared.
public class UnsharedConcreteFlyweight extends Flyweight { public UnsharedConcreteFlyweight(String extrinsic) { super(extrinsic); } @Override public void operate(int extrinsic) { System.out.println("Specific information not shared Flyweight:" + extrinsic); } }
- FlyweightFactory class
A shared element factory is used to create and manage Flyweight objects, mainly to ensure reasonable sharing of Flyweight. When a user requests a Flyweight, the FlyweightFactory object provides a created instance or creates an instance.
public class FlyweightFactory { //Define a pool container private static HashMap<String, Flyweight> pool = new HashMap<>(); //Xiangyuan factory public static Flyweight getFlyweight(String extrinsic) { Flyweight flyweight = null; if(pool.containsKey(extrinsic)) { //The object exists in the pool flyweight = pool.get(extrinsic); System.out.print("already existing " + extrinsic + " Directly from the pool---->"); } else { //Create meta objects based on external state flyweight = new ConcreteFlyweight(extrinsic); //Put into the pool pool.put(extrinsic, flyweight); System.out.print("establish " + extrinsic + " And remove it from the pool---->"); } return flyweight; } }
- Client client
public class Client { public static void main(String[] args) { int extrinsic = 22; Flyweight flyweightX = FlyweightFactory.getFlyweight("X"); flyweightX.operate(++ extrinsic); Flyweight flyweightY = FlyweightFactory.getFlyweight("Y"); flyweightY.operate(++ extrinsic); Flyweight flyweightZ = FlyweightFactory.getFlyweight("Z"); flyweightZ.operate(++ extrinsic); Flyweight flyweightReX = FlyweightFactory.getFlyweight("X"); flyweightReX.operate(++ extrinsic); Flyweight unsharedFlyweight = new UnsharedConcreteFlyweight("X"); unsharedFlyweight.operate(++ extrinsic); } }
The operation results are as follows:
establish X And remove it from the pool---->specific Flyweight:23 establish Y And remove it from the pool---->specific Flyweight:24 establish Z And remove it from the pool---->specific Flyweight:25 already existing X Directly from the pool---->specific Flyweight:26 Specific information not shared Flyweight:27
From this result, we can see that when creating X, Y and Z for the first time, they are created first and then taken out of the pool. When creating X for the second time, they are directly taken out of the pool because they already exist in the pool. This is the sharing mode.
- UML
Internal status and external status
-
The above definition of shared meta pattern puts forward two requirements for us: fine granularity and shared objects. We know that allocating too many objects to the application will not only damage the performance of the program, but also easily cause memory overflow. To avoid this situation, the sharing technology is used. Here we need to mention the internal state and external state.
-
Because fine-grained objects are required, there will inevitably be a large number of objects with similar properties. At this time, we will divide the information of these objects into two parts: internal state and external state.
-
Internal state refers to the information shared by the object, which is stored in the shared meta object and will not change with the change of the environment; External state refers to a mark on which an object can depend. It is a state that changes with the environment and cannot be shared.
-
Let's take the simplest example. We've all played chess and card games. For example, go and checkers have a large number of pieces. Go and Gobang only have black and white, and checkers have a little more colors, but they don't change much, so the color of the pieces is the internal state of the pieces; The difference between each piece is the difference in position. For our pieces, the color of the pieces is fixed, but the position is changed, so the azimuth coordinate is the external state of the pieces.
-
So why use the meta model here? You can imagine the example of chess games mentioned above, such as go. Theoretically, there are 361 empty spaces for chess pieces. Under normal circumstances, there may be two or three hundred chess pieces in each game. Because of the limited memory space, it is difficult for a server to support more players to play go games. If you use the sharing mode to process chess pieces, Then the pawn object can be reduced to only two instances, which solves the problem of object overhead.