Classification of 23 design patterns
1, Overview
Definition of Flyweight pattern: using sharing technology to support reuse of a large number of fine-grained objects. It can reduce the number of objects to be created and avoid the cost of a large number of similar classes by sharing the existing oak, so as to improve the utilization of system resources.
The main solution is that when there are a large number of objects, it may cause memory overflow. We abstract the common part. If there are the same business requests, we directly return the existing objects in memory to avoid re creation.
advantage
Only one copy of the same object is saved, which reduces the number of objects in the system, thus reducing the pressure on memory caused by fine-grained objects in the system.
shortcoming
In order to improve the complexity of the system, it is necessary to separate the external state and the internal state, and the external state has the inherent nature, which should not change with the change of the internal state, otherwise it will cause the system confusion.
scene
1. The system has a large number of similar objects.
2. Scenarios that require a buffer pool.
2, Implementation
There are two states in the sharing mode:
- Internal state, that is, the shareable part that will not change with the change of environment;
- External state refers to the unshared part that changes with the environment. The key to the implementation of the sharing mode is to distinguish the two states in the application and externalize the external state.
1. Structure diagram
The main roles of the sharing mode are as follows.
- Abstract membership role (Flyweight): it is the base class of all the concrete membership classes. It is the public interface that the concrete membership specification needs to implement. The external state of the non membership is passed in as a parameter through a method.
- Concrete Flyweight role: implements the interface specified in the abstract role.
- Unshareable flyweight role: it is an external state that cannot be shared. It is injected into the relevant methods of specific sharers in the form of parameters.
- Flyweight Factory role: responsible for creating and managing the role. When a customer object requests a sharing object, the sharing factory checks whether there is a qualified sharing object in the system, and if so, provides it to the customer; if not, creates a new sharing object.
PS: the UML structure diagram can be referred to. The example implementation is not completed according to the UML diagram. It can be implemented flexibly;
2. Implementation
- Connection pool class
package cn.missbe.model.flyweight; import java.util.ArrayList; import java.util.List; /** * Copyright (c) 2020. * Email: love1208tt@foxmail.com * @author lyg 2020/4/28 11:11 am * description: * Sharing mode: reusing objects * Database connection pool, maintain database connection reuse created connection **/ public class DatasourceConnectionPool { private List<DatasourceConnection> connections = new ArrayList<>(); public synchronized DatasourceConnection getConnection(){ for (DatasourceConnection datasourceConnection : connections) { ///Find a less busy connection if (!datasourceConnection.isBusy()) { return datasourceConnection; } } DatasourceConnection connection = new DatasourceConnection(); connections.add(connection); return connection; } public void register(DatasourceConnection connection) { this.connections.add(connection); } public int size(){ return this.connections.size(); } }
- Connection class
package cn.missbe.model.flyweight; /** * Copyright (c) 2020. * Email: love1208tt@foxmail.com * @author lyg 2020/4/28 11:10 am * description: * Simulate database connection object **/ public class DatasourceConnection { /**Database connection object*/ private Object datasourceConnection; /**Is the connection busy*/ private boolean isBusy; public DatasourceConnection() { this("datasourceConnection", false); } public DatasourceConnection(Object datasourceConnection, boolean isBusy) { this.datasourceConnection = datasourceConnection; this.isBusy = isBusy; } public Object getDatasourceConnection() { return datasourceConnection; } public void setDatasourceConnection(Object datasourceConnection) { this.datasourceConnection = datasourceConnection; } public boolean isBusy() { return isBusy; } public void setBusy(boolean busy) { isBusy = busy; } public void simulateProcessingTasks(){ ///Start processing tasks, can't be reused by others this.isBusy = true; System.out.println("Before Processing:" + this); try { ///Simulation task processing Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } ///Processing completed, can be used again isBusy = false; System.out.println("After Processing:" + this); } @Override public String toString() { return "DatasourceConnection{" + "datasourceConnection=" + datasourceConnection + ", isBusy=" + isBusy + '}'; } }
- Main class
package cn.missbe.model.flyweight; /** * Copyright (c) 2020. * Email: love1208tt@foxmail.com * @author lyg 2020/4/28 11:18 am * description: * Sharing element mode: reusing the created objects and adopting this idea in the constant pool / database connection pool of String **/ public class Main { @SuppressWarnings("all") public static void main(String[] args) throws InterruptedException { DatasourceConnectionPool pool = new DatasourceConnectionPool(); for (int i = 0; i < 5; i++) { pool.register(new DatasourceConnection("datasourceConnection:"+i,false)); } for (int i = 0; i < pool.size(); i++) { new Thread(()->{ pool.getConnection().simulateProcessingTasks(); }).start(); ///The current thread sleeps, waiting for the connection to finish processing the task, testing and reusing the created object Thread.sleep(1000); } } }