设计模式之享元模式
# 设计模式之享元模式
# 一、简介
运用共享技术,主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式
# 二、实现方式
用 HashMap 存储这些对象
- 创建一个接口
Shape.java
public interface Shape {
void draw();
}
1
2
3
2
3
创建实现接口的实体类
Circle.java
public class Circle implements Shape { private String color; private int x; private int y; private int radius; public Circle(String color){ this.color = color; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public void setRadius(int radius) { this.radius = radius; } @Override public void draw() { System.out.println("Circle: Draw() [Color : " + color +", x : " + x +", y :" + y +", radius :" + radius); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23创建一个工厂,生成基于给定信息的实体类的对象
import java.util.HashMap; public class ShapeFactory { private static final HashMap<String, Shape> circleMap = new HashMap<>(); public static Shape getCircle(String color) { Circle circle = (Circle)circleMap.get(color); if(circle == null) { circle = new Circle(color); circleMap.put(color, circle); System.out.println("Creating circle of color : " + color); } return circle; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16使用该工厂,通过传递颜色信息来获取实体类的对象
public class FlyweightPatternDemo { private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" }; public static void main(String[] args) { for(int i=0; i < 20; ++i) { Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor()); circle.setX(getRandomX()); circle.setY(getRandomY()); circle.setRadius(100); circle.draw(); } } private static String getRandomColor() { return colors[(int)(Math.random()*colors.length)]; } private static int getRandomX() { return (int)(Math.random()*100 ); } private static int getRandomY() { return (int)(Math.random()*100); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 三、应用场景
# 1、字符串常量池
详见:JVM在内存中缓存了字符串
# 2、八种基本类型的包装类和对象池
这也是我们不能使用==
来判断数据是否相等的原因,当我们定义了Integer a = xx
,经过编译后,会调用Integer.valueOf
方法,方法里面的逻辑会判断是否在cache-128~127
中,如果是的话,直接返回这个cache,否则创建一个Integer。
# 3、Redis连接池
每次从Redis连接池中获取连接时,会复用连接,首先会从空闲连接idleObjects
中去拿,没有则创建
p = (PooledObject)this.idleObjects.pollFirst();//从idleObjects中取,复用连接
if (p == null) {
p = this.create();//创建连接
if (p != null) {
create = true;
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
使用完后,释放连接,放回idleObjects