This is the 29th day of my participation in the More Text Challenge. For more details, see more Text Challenge
👉 Design mode directory
What is Flyweight?
concept
The Flyweight Pattern is a structural Pattern used to reduce the performance cost of object creation and destruction to reduce memory usage. Object-oriented language can bring to our development flexibility and extensibility, and more in line with the people’s way of thinking, but this would make our system create many objects, which makes our system performance degradation, so you can use one buffer pool to store these repeated use of objects, reduce the number of creation and destruction repeatedly, The idea behind the enjoy meta-pattern is to reuse objects.
There are also many examples of enjoy yuan in our life, such as chess pieces of Go, shared bikes, and swimming pools, which are used repeatedly. Thread pools, String constant pools, and database connection pools are common in development to avoid creating a “pool” of objects.
advantages
Lower memory and improve performance. When we want to use an object, we just need to go to the “pool” to get it. We don’t need to create it again, saving the system overhead of constantly creating and destroying it.
disadvantages
Increases program complexity. The granularity of objects needs to be refined and the parts that cannot be shared can be externalized to achieve sharing, which increases the complexity of coding and the difficulty of understanding code.
The principle of
“+” means compliance, and “-” means noncompliance or irrelevant
The principle of | Open the closed | Single responsibility | Di milt | Replacement on the Richter scale | Dependency inversion | Interface segregation | Synthesis of reuse |
---|---|---|---|---|---|---|---|
+ | + | – | – | + | – | + | |
Applicable scenario
- You need a large number of the same objects or a class of objects with many of the same parts, and creating or destroying these objects has a significant performance overhead. I can just take these objects and pull them out and I can put them in a pool that’s not changing, and I can just pull them out when I need to.
- The system doesn’t depend on the state of these objects, it just uses them.
- An object can be divided into inner and outer parts. The inner part can be used repeatedly, and the outer part can be defined by the user.
How to implement
To implement the enjoy meta pattern, you need five things:
- Enjoy metaclass interface (Flyweight) : Defines the specification for all enjoy metaclasses to implement.
- Concrete Flyweight: Implements the Enjoy metaclass interface.
- Unsharable Flyweight: Defines the specification that the Unsharable Flyweight will implement.
- Concrete Unsharable Flyweight: Implements the Unsharable Flyweight interface.
- The Flyweight Factory class creates and manages the Flyweight metaclass objects.
On the class diagram
It’s a little bit more complex, which can be understood in the following code.
In the code
Huizhou is a tourist resort (I speak for Huizhou), Honghua Lake is a very suitable place for cycling, there is now a bike shop, which rents bikes in Honghua Lake for tourists to ride around the lake, FlyweightFactory provides bikes, if there is not enough bikes, they will buy new bikes. Visitors (ConcreteUnsharableFlyweight)? After riding the bike will be returned to the car shop.
/** * Created on 2021/6/3. **@author xuxiaobai
*/
public class FlyweightTest {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory(4);
// Simulate ten people to pick up the car
for (int i = 0; i < 20; i++) {
int finalI = i;
new Thread(()->{
Flyweight flyweight = factory.getFlyweight();
flyweight.operate(new ConcreteUnsharableFlyweight("Xiao Ming"+ finalI +"No."));
try {
// Ride a bike happily
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Return after riding
flyweight.release();
}).start();
}
try {
// Sleep for five seconds and let the thread run out
Thread.sleep(20000);
} catch (InterruptedException e) {
}
System.out.println("Number of bicycles in the factory:"+factory.getFlyweightSize());
/** * Result: * Current id:1 occupied * Unlocked successfully! * Current ID :2 Occupied * Unlocking succeeded! * Current bike ID :1 Current bike ID :2 Xiaoming 1 riding bicycle * Xiaoming 0 riding bicycle * Current ID :3 Occupied * Unlocked successfully! * Current bike ID :3 Xiaoming no. 2 bike * No free bike, please wait * No free bike, please wait * Current ID :3 occupied * Unlocked successfully! * Current cycle ID :3 Xiaoming no. 4 riding * No idle cycle, please wait * Current cycle ID :3 Xiaoming No. 5 riding * No idle cycle, please wait * Current ID :4 occupied * Unlocked successfully! * Current cycle ID :4 Xiaoming no. 19 riding * No idle cycle, please wait * Current cycle ID :4 Xiaoming No. 3 riding * No idle cycle, please wait * Current ID :5 Occupied * Unlocked successfully! * Current bike ID :5 Xiaoming no. 17 bike * No idle bike, please wait * Current bike ID :5 Xiaoming No. 18 bike * Current ID :1 returned * Current ID :3 returned * Current ID :2 returned * Current ID :1 Occupied * Unlocked successfully! * Current bicycle ID :1 Xiao Ming 15 riding bicycle * Current ID :2 Occupied * Unlocked successfully! * Current bicycle ID :2 Xiaoming 16 riding bicycle * Current ID :3 Occupied * Unlocked successfully! * Current bike ID :3 Xiaoming 14 riding bike * No idle bike, please wait * Current ID :3 returned * Current ID :3 returned * Current ID :3 occupied * Unlocked successfully! * No idle bike, please wait * Current bike ID :3 Xiaoming no. 13 bike * Current ID :4 returned * Current ID :4 returned * Current ID :4 occupied * Unlocked successfully! * Current bike ID :4 Xiaoming No. 12 bike * No idle bike, please wait * Current ID :5 returned * Current ID :5 returned * Current ID :5 occupied * Unlocked successfully! * No idle bike, please wait * Current bike ID :5 Xiaoming 11 bike * Current ID :1 returned * Current ID :3 returned * Current ID :2 returned * Current ID :1 Occupied * Unlocked successfully! * Current ID :2 Occupied * Unlocking succeeded! * Current bicycle ID :2 Xiaoming no. 9 riding bicycle * Current ID :3 Occupied * Unlocked successfully! * Current bike ID :3 Xiaoming no. 8 bike * No idle bike, please wait * Current bike ID :1 Xiaoming No. 10 bike * Current ID :3 Returned * Current ID :3 occupied * Unlocked successfully! * No idle bike, please wait * Current bike ID :3 Xiaoming no. 7 bike * Current ID :4 returned * Current ID :4 occupied * Unlocked successfully! * Current bike ID :4 Xiaoming no. 6 Bike * Current ID :5 Returned * Current ID :3 returned * Current ID :1 returned * Current ID :2 returned * Current ID :3 returned * Current ID :4 Returned * Factory Number of bikes: 6 */}}/** ** ** ** ** **
class FlyweightFactory {
private List<Flyweight> flyweights = new ArrayList();
private int flyweightSize=0;
public FlyweightFactory(int num) {
for (int i = 1; i < num; i++) {
flyweights.add(newConcreteFlyweight(i)); flyweightSize++; }}/** * Only one person can pick up the bike at a time *@return* /
public synchronized Flyweight getFlyweight(a) {
Flyweight flyweight1 = getOneFlyweight();
if(flyweight1 ! =null) return flyweight1;
try {
// Simulate wait
Thread.sleep(500);
} catch (InterruptedException e) {
}
// Let's see if there's a bus coming back
flyweight1 = getOneFlyweight();
if(flyweight1 ! =null) return flyweight1;
// I really didn't wait to buy a new car
return newFlyweight();
}
/** * To buy a new bike *@return* /
private synchronized Flyweight newFlyweight(a){
ConcreteFlyweight flyweight = new ConcreteFlyweight(this.flyweightSize);
flyweightSize++;
flyweights.add(flyweight);
return flyweight;
}
/** * Car shop inside *@return* /
private Flyweight getOneFlyweight(a) {
Iterator<Flyweight> iterator = flyweights.iterator();
while (iterator.hasNext()){
Flyweight flyweight = iterator.next();
if (flyweight.occupy()) {
System.out.println("Successful unlocking!");
return flyweight;
}
}
System.out.println("No bicycles available. Please wait.");
return null;
}
public int getFlyweightSize(a){
returnflyweightSize; }}/** * Specific enjoy metaclasses * simulation bicycle class */
class ConcreteFlyweight implements Flyweight {
private int id;
UnsharableFlyweight unsharableFlyweight;
//0 is idle, 1 is occupied
private volatile int state = 0;
public ConcreteFlyweight(int id) {
this.id = id;
}
/** * ride a bike *@param unsharableFlyweight
*/
@Override
public synchronized void operate(UnsharableFlyweight unsharableFlyweight) {
System.out.print(Current Cycle ID:+id+"");
unsharableFlyweight.operate();
}
/** * Occupy **@returnTrue: The occupation is successful. False The occupation fails */
@Override
public synchronized boolean occupy(a) {
if (state == 0) {
state = 1;
System.out.println("The current id." + id +"Occupied");
return true;
}
return false;
}
/** * release/return */
@Override
public synchronized void release(a) {
System.out.println("The current id." + id +"Returned");
this.state = 0; }}/** * Enjoy metaclass interface * simulation car class */
interface Flyweight {
void operate(UnsharableFlyweight unsharableFlyweight);
void release(a);
boolean occupy(a);
}
/** * Specific non-enjoy metaclasses * simulate cyclists */
class ConcreteUnsharableFlyweight implements UnsharableFlyweight {
private String name;
public ConcreteUnsharableFlyweight(String name){
this.name=name;
}
@Override
public void operate(a) {
System.out.println(name+"Ride a bike"); }}/** * Non-shared metaclass interface */
interface UnsharableFlyweight {
void operate(a);
}
Copy the code
Here is nearly 200 lines of code, but also added a lot of comments, no credit but also hard work, I hope you can see in my hard work to give a thumbs up 👍.
conclusion
The focus of share element mode is to share and reuse objects, the fine-grained objects are stored, the next suitable for directly applicable, do not need to create again, to avoid the cost of creating a large number of similar objects, so as to improve the performance of the system. A lot of pooling techniques are based on the enjoy element pattern, but the enjoy element pattern is not applicable everywhere, only when there is a large number of objects created for each type, and the system does not depend on the state of those objects.
The enjoy meta-pattern is very similar to the singleton pattern, and I once wondered if the enjoy meta-pattern should be included in the creation pattern, but now that I’ve learned it, I find that my doubts were wrong. The enjoy meta pattern should be a structural pattern, which manages a set of objects that are combined with the management class and focus on the structure of the object. The singleton pattern is focused on whether the objects of the class are single, ensuring that there is only one object per class, while the enjoy pattern is designed to save memory and improve performance, and does not guarantee that there is only one object per class. If there are not enough objects, new ones will be created.
— — — — — — — — — — — — — — —
The more you know, the more you don’t know.
If you have questions about this article, please comment directly or send me a personal message. If you think my writing is good, you can also support me by clicking “like”
Without permission, shall not be reproduced!