文章目录
目录:https://blog.youkuaiyun.com/qq_52681418/article/details/114828850
设计模式-享元模式
享元模式 的宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。
假设一个火车票查询系统,查询时搜索车票并构建车票对象,然后其他人也搜索这张票,于是可能同时存在多个一样的对象,浪费资源。使用享元模式可以在第一个人查询时构建车票对象,其他人查询时直接获得该对象。
如何实现呢?假设有多种颜色的图形,我们根据颜色来获得不同颜色的图形对象,我们获取多次,某一颜色可能获取多次。多次获取相同颜色对象时,不再重复的去实例化,而是拿第一次获取时实例化的对象。
将第一次获取的对象存放在map中(以颜色为key),再次获取相同对象时,从map获取:
- map中没有,实例化一个,并存放在map中
- map中有,获得map里的对象,不再实例化
这样做的好处是:仅在第一次获取时才会实例化某个对象。
1.假设你有个图形(不考虑形状、只考虑颜色)
public class Shape {
private String colorName; //区分不同的对象
private long value; //对象创建时间戳
//构造器
public Shape(String colorName) {
this.value= System.currentTimeMillis();
this.colorName = colorName;
}
public void sun() {
System.out.println("创建:"+value+",颜色="+colorName);
}
}
外部每次获取红色图形时会 new Shape(“红色”),这就会出现很多个红色图形对象。
2.现在我们通过一个类来获取此对象(可以直接写在上面的类中,不过不符合单一职责原则)
public class ShapeFactory {
//存储已经创建过的对象
private static final HashMap<String,Shape> map=new HashMap<String, Shape>();
//根据颜色来获取图形,获取不到则构建并添加到map
public static Shape getShape(String colorName){
Shape shape= map.get(colorName);
if (shape==null){//如果map中没有则创建并加如map
shape=new Shape(colorName);
map.put(colorName,shape);
}
return shape;
}
}
每次根据颜色获取时,先查map中是否存在该颜色的对象,如果有就不再实例化了。
3.开始模拟获取
添加延迟表明,每次获取的时间不同。
public class Goods {
public static void main(String[] args) throws InterruptedException {
Shape shape1 =ShapeFactory.getShape("蓝色");
Thread.sleep(1000);
Shape shape2 =ShapeFactory.getShape("红色");
Thread.sleep(1000);
Shape shape3 =ShapeFactory.getShape("绿色");
Thread.sleep(1000);
Shape shape4 =ShapeFactory.getShape("蓝色"); //再次获取蓝色
shape1.sun();
shape2.sun();
shape3.sun();
shape4.sun();
}
}
运行结果:
可以发现:两次蓝色的时间戳是一样的,表明他们调用的是同一个对象。
享元和单例的区别:
如果是单例,则只有一个图形对象。
如果是享元,可以有多个图形对象,但相同颜色的只有一个。