享元(Flyweight)模式的核心思想就是:如果一个对象创建后就不会改变,那么就没必要重复创建,直接将原来创建的返回就行了,这样既可以节省内存,也可以减少创建对象的过程,提供运行速度
享元模式在java的标准库中也有应用,比如Byte,Integer是不变类,因此反复创建同一个值的包装类是没有必要的,如果通过
Integer.valueOf()
这个静态工厂创建的实例,当传入的值是在-128至+127之间时,会直接返回Integer的实例
在实际使用过程中,享元模式主要应用于缓存,即客户端重复请求某些对象,不必每次创建,而是直接返回内存中缓存的数据,其本质就是缓存共享对象,降低内存消耗
优点:相同的对象只存储一份,降低系统内对象的数量
缺点:为了使对象可以共享,需要将一些不能共享的状态外部化,增加了程序的复杂性
示例:
现在有个神奇的积木盒,里面有方形和圆形积木,现在有几个孩子过来从盒子里面取积木玩。
public class FlyweightDemo {
public static void main(String[] args) {
Box box = new Box();
box.get(new Square()); // 创建了一个新积木呀: 方形积木
box.get(new Square()); // 方形积木
box.get(new Circle()); //创建了一个新积木呀: 圆形积木
}
// 神奇的积木盒子
static class Box{
private final Map<String,ToyBrick> cache = new HashMap<>();
// 获取想要的积木
public void get(ToyBrick toyBrick){
// 先从缓存取
ToyBrick toyBrickName = cache.get(toyBrick.getName());
// 不存在,则创建
if (toyBrickName == null){
// 创建
toyBrick = toyBrick.create();
System.out.println("创建了一个新积木呀: "+toyBrick.getName());
// 加入缓存
cache.put(toyBrick.getName(),toyBrick);
}else {
// 缓存有,则返回
System.out.println(toyBrickName.getName());
}
}
}
// 抽象积木
interface ToyBrick{
ToyBrick create();
String getName();
}
static class Square implements ToyBrick{
@Override
public Square create() {
return new Square();
}
@Override
public String getName() {
return "方形积木";
}
}
static class Circle implements ToyBrick{
@Override
public Circle create() {
return new Circle();
}
@Override
public String getName() {
return "圆形积木";
}
}
}