java23 design pattern---class10, FlyWeight

1. Basic introduction

1. Definition

FlyWeight mode (FlyWeight), also known as fly weight mode, is often used when there are a lot of fine-grained objects that are reused. It is essentially a shared technology.

2. Advantages

By using the Flyweight Pool, users do not need to go to new when calling an object, and only need to get it directly from the Flyweight Pool, saving memory space.
注:太多的对象不仅会影响性能,更严重的情况下可能会造成内存溢出

3. Disadvantages

1) The logic will be more complicated.
2) For some objects that cannot be taken out directly from the Flyweight Pool, you still need to go to new. At this time, it takes longer to obtain the object by using the Flyweight mode.

4. Role

1) Abstract Flyweight class

Interface/abstract class

2) Specific Flyweight Class

Concrete subclasses that implement interfaces or abstract classes, these subclasses will be reused a lot, and these subclass objects are fine-grained.

3) Flyweight factory class

The factory is actually a Flyweight Pool

4) Combination Flyweight Class

The combined flyweight class is an overall class that relies on the basic flyweight class. For example, if there are characters A and B in the flyweight pool, we can actually use these two character objects to form an AB string, which is a combined flyweight class.

5. Internal state and external state

Fine-grained objects, when there are a large number of objects, they are inevitably similar in nature. How to distinguish so many different fine-grained objects? At this time, we divide the information of these objects into two parts: internal state and external state.

  • The internal state refers to the information shared by the object, which is stored in the flyweight object and will not change with changes in the environment;
  • External state refers to a mark that an object can rely on. It is a state that changes with the environment and cannot be shared.
                 如何理解内部状态和外部状态呢?

For example, in a tank battle, there are different types of bullets. These bullets are changed due to different internal states. For example, whether it is an incendiary bomb or a smoke bomb depends on its internal state. But our tank can fire bullets in different directions, and the azimuth coordinates of the bullets are an external state of the bullets.

Another example is Go, with only two black and white pieces. The internal state controls the color, while the external state controls the position of the chess in the game.

Two, application scenarios

1. Thread pool

2、String

There is a string constant pool in the JVM. For example, when String="a", it is not directly in the heap new String("a"), but will go to the constant pool for query first. If there is "a" in the constant pool, it will be directly Returns the reference address of the string "a" in the constant pool. String addition is actually calling append of StringBuilder() and then toString, so the added reference is not in the constant pool but in the heap.

Insert picture description here

3、Integer

In Integer, there are also some existing objects (-128,127), these objects are put into the buffer, when we use Integer a=1;or Integer a=Integer.ValueOf(1), it will first match the objects in the buffer, if the buffer has it, it will return directly If there is no object in the buffer, for example, if 128 is not in the buffer, you can onlyreturn Integer a=new Integer(128);

Insert picture description here

4. Gobang

In the Gobang game, if we need more than 500 black and white stones in total, we need more than 500 objects without using Flyweight mode or Singleton mode new. However, if we use Flyweight mode, we can have only two objects. : One black chess, one white chess. [注:单例模式也可以实现], This greatly saves memory space, and also saves new time. Space and time performance have been greatly improved.

Three, use with other modes

Flyweight pattern usually associated with 单例模式, 组合模式, 工厂模式with use.

1) Singleton mode

The factory can use singleton mode. ( 前提是工厂不是泛型工厂)

2) Combination mode

The composite flyweight model uses a combination model

3) Factory model

The factory is actually a Flyweight Pool

Four, code analysis

//Abstract Flyweight

package pattern.flyweight;

public abstract class FlyWeight {
    
    
//内部状态
String instate;
//外部状态
String outstate;
public FlyWeight(String outstate) {
    
    
	this.instate=outstate;
}
//与外部状态相关的逻辑操作
abstract void operation();
//获取或者设置内部状态
public String getInstate() {
    
    
	return instate;
}
public void setInstate(String instate) {
    
    
	this.instate = instate;
}

}

// Specific enjoyment

package pattern.flyweight;
public class A extends FlyWeight{
    
    

	public A(String outstate) {
    
    
		super(outstate);
		// TODO Auto-generated constructor stub
	}
//根据外部状态进行一系列的逻辑操作
	@Override
	void operation() {
    
    
		// TODO Auto-generated method stub
		System.out.println(outstate);
	}


}

//Flyweight Factory

package pattern.flyweight;

import java.util.HashMap;
import java.util.Map;

//泛型时,不能用单例模式,否则泛型将会没有意义
public class FlyWeightFactory {
    
    
private FlyWeightFactory() {
    
    };
// volatile是避免重排序
private static volatile FlyWeightFactory INSTANCE = null;

public static FlyWeightFactory getINSTANCE() {
    
    
	if (INSTANCE == null) {
    
    
		synchronized (FlyWeightFactory.class) {
    
    
			if (INSTANCE == null)
				INSTANCE = new FlyWeightFactory();
		}
	}
	return INSTANCE;
}
 
static Map<Character,FlyWeight> FlyWeightMap=new HashMap<Character,FlyWeight>();

public  FlyWeight getConcreteFlyWeight(char c) {
    
    
	if(!FlyWeightMap.containsKey(c))
		FlyWeightMap.put(c,new A());
	return FlyWeightMap.get(c);
}
}

//Test class

package pattern.flyweight;
public class Main {
    
    
	public static void main(String[] args) {
    
    
		/*
		 * Integer a=Integer.valueOf(3);//有缓存机制 Integer c=new Integer(3);//没有用到缓存机制
		 * Integer b=new Integer(3); Integer d=3;//有用到缓存机制 Integer e=129; Integer
		 * f=129;//超过了缓存池 System.out.println(a==d); System.out.println(e==d);
		 * System.out.println(c==b);
		 * 
		 * String a0="a"; String a1="b"; String a2="a"+"b"; String b="ab"; String
		 * c="ab"; String a=a0+a1;
		 * System.out.println(a==b);//字符串相加其实是StringBuilder.append()然后toString
		 * System.out.println(a.intern()==b);//intern是找常量池中的引用
		 * System.out.println(b==c);//两个都指向常量池中
		 * System.out.println(a2==b);//如果是定义的时候直接相加,编译器会进行优化,直接看成String a2="ab";
		 */
		FlyWeight a=FlyWeightFactory.getINSTANCE().getConcreteFlyWeight('a',"outstate");
		FlyWeight b=FlyWeightFactory.getINSTANCE().getConcreteFlyWeight('a',"outstate");
		System.out.println(a==b);
	}
}

Insert picture description here
UML graphics:
Insert picture description here

It’s really hard to explain the Flyweight mode in a few lines of code, and I haven’t found a more suitable example, so I can only briefly introduce the basic Flyweight mode here. The test in the article only tests whether a and b refer to the same reference. The advantages of the Flyweight mode in some relatively small programs are really difficult to reflect. If you still have a lot of doubts, you can check the java source code. The thread pool and Integer buffer are all very good use of the Flyweight mode.

Guess you like

Origin blog.csdn.net/m0_51801058/article/details/114254746