Sharing element mode
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 for application. 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 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 this problem: * * use the unique identification code to judge. If it exists 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, is returned. If not, a string is created and saved in the string cache pool. 2. 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 the system will be confused.
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.
Elder martial brother, the system is down again
"Senior brother, the registration system is down again, and the memory overflows OutOfmemory!!!"
Memory overflow is very familiar to programmers. It is nothing more than two cases
- Memory leak: an unconscious code defect that causes a memory leak. The jvm cannot get contiguous memory space.
- Too many objects: too many objects are generated and memory is exhausted.
The system is an examination registration system. When registering for the examination, you need to fill in the basic information, and select the subject and place of the examination.
Registration information:
@Data @AllArgsConstructor @NoArgsConstructor public class SignInfo { //Candidate id private String id; //Examination place private String location; //Examination subjects private String subject; //Mailing address private String postAddress; }
The reason for the system downtime is that there are too many objects, resulting in insufficient memory. Then we should think of using a technology to reduce objects, so we think of the object pool
-
Object pool
We define a pool container in which objects are stored
-
Provide client access interface
When there are available objects in the pool, get them directly in the pool. Otherwise, create an object and put it into the pool.
Create object pool
public class SignInfo4Pool extends SignInfo { //Define a key extracted from an object pool private String key; public SignInfo4Pool(String _key){ this.key = _key; } public void setKey(String key){ this.key = key; } public String getKey(){ return this.key; } }
In the object pool, once an object is generated, it must have a unique and accessible status flag, and the declaration cycle of the object in the pool is determined by the pool container, not the user
Factory class with object pool
public class SignInfoFactory { private static HashMap<String, SignInfo> pool = new HashMap<>(); //Object factory of registration information public static SignInfo getSignInfo(String key){ SignInfo result = null; if(!pool.containsKey(key)){ System.out.println(key+"-------Create an object and place it in the pool"); result = new SignInfo4Pool(key); pool.put(key, result); }else { System.out.println(key+"Object exists and is obtained directly from the pool"); result = pool.get(key); } return result; } }
Client class
public class Client { public static void main(String[] args) { //Initialize object pool for (int i = 0; i < 4; i++) { String subject = "subject"+i; //Initialization address for (int j = 0; j < 30; j++) { String key = subject + "Examination place"+j; SignInfoFactory.getSignInfo(key); } } SignInfoFactory.getSignInfo("Subject 1 test location 1"); } }
This is the meta model.
Definition of meta mode
Meta sharing mode is an important implementation of pool technology. Let's look at the external and internal states of objects.
-
External status: the external status is a mark that the object depends on. It changes with the environment, such as the string of test subjects and places in the example. Is a unique index value.
-
Internal status: internal status is the information that can be shared by the object. It is stored inside the shared meta object and will not change with the change of the external environment, such as id, postAddress, etc. in the example. They can be used as dynamic additional information of an object and do not need to be directly stored in an object. They belong to the part that can be shared.
Meta pattern class diagram
-
Flyweight - Abstract meta role
In short, it is an abstract class of a product, which defines the mouth or implementation of the external state and internal state of the object at the same time.
-
ConcreteFlyweight - specific roles
A specific product class implements the business defined by the abstract role. In this role, it should be noted that the internal state is independent of the environment. An operation should not change the internal state and modify the external state at the same time. This is not allowed.
-
unsharedConcreteFlyweight -- unshareable meta role
Objects with no external state or security requirements (such as thread safety) that cannot use sharing technology generally do not appear in the sharing factory.
-
FlyweightFactory - Xiangyuan factory
Construct a pool container and provide methods to get objects from the pool.
Abstract meta role
public abstract class Flyweight { //Internal state private String intrinsic; //External state private final String Extrinsic; //It is required that the meta role must accept external status public Flyweight(String extrinsic) { this.Extrinsic = extrinsic; } // public abstract void operate(); //get and set methods of internal state public String getIntrinsic() { return intrinsic; } public void setIntrinsic(String intrinsic) { this.intrinsic = intrinsic; } }
Note: in program development, the attribute that only needs to be assigned once is set to final type to avoid logical confusion caused by unintentional modification.
Specific meta role
public class ConcreteFlyweight extends Flyweight { //Accept external status public ConcreteFlyweight(String extrinsic) { super(extrinsic); } //Logical processing according to external state @Override public void operate() { } }
Xiangyuan factory
public class FlyweightFactory { //Define a pool container private static HashMap<String, Flyweight> pool = new HashMap<>(); //Xiangyuan factory public static Flyweight getFlyweight(String Extrinsic){ //Object to return Flyweight flyweight = null; //The object exists in the pool if(pool.containsKey(Extrinsic)){ pool.get(Extrinsic); }else { //Create meta objects based on external state flyweight = new ConcreteFlyweight(Extrinsic); //Put it in the pool pool.put(Extrinsic, flyweight); } return flyweight; } }