在软件系统中,经常会出现资源浪费的情况,例如在计算机内存中同时存在多个完全相同的或者非常相似的对象,当这些对象的数量很多,会占用很多的内存,并且重复的创建和销毁,使得GC任务繁重,内存占用居高不下,这使得系统运行代价过高。为了解决这个问题,可以将已经创建的对象的缓存起来,当下一次要再要创建新对象时,先判断缓存池中是否已经存在该对象了,如果存在就直接拿出来用,如果不存在,就新实例化一个对象——享元模式就是这么做的。
定义:使用共享对象可有效地支持大量的细粒度的对象。
结构:
- 抽象享元:接口或者抽象类,定义统一的接口
- 具体享元:享元对象的具体实现类,指定内部状态
- 享元工厂:负责管理享元对象缓存池和创建享元对象
适用场景:
- 系统中存在大量的相似对象
- 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,即对象没有特殊身份
- 需要缓冲池的场景
UML类图:
下面就是享元模式的代码实现:
FlyWeight:
public interface Shape {
void draw();
}
public class Circle implements Shape{
private String color;
public Circle(String color){
this.color = color;
}
@Override
public void draw() {
System.out.println("画"+color+"的圆");
}
}
FlyWeightFactory:
public class ShapeFactory {
private static Map<String,Shape> shapes = new HashMap();
private static int num=0;
public static Shape getShape(String key){
Shape shape= shapes.get(key);
if(shape!=null){
return shape;
}
num++;
shape = new Circle(key);
shapes.put(key, shape);
return new Circle(key);
}
public static int getSum(){
return num;
}
}
Test:
public class Test {
public static void main(String[] args){
Shape shape1 = ShapeFactory.getShape("红色");
shape1.draw();
Shape shape2 = ShapeFactory.getShape("灰色");
shape2.draw();
Shape shape3 = ShapeFactory.getShape("绿色");
shape3.draw();
Shape shape4 = ShapeFactory.getShape("红色");
shape4.draw();
Shape shape5 = ShapeFactory.getShape("灰色");
shape5.draw();
Shape shape6 = ShapeFactory.getShape("灰色");
shape6.draw();
System.out.println("一共实例化了"+ShapeFactory.getSum()+"个对象");
}
}
总结:上面的代码实现还是比较简单的,不过在某些特定场景非常重要。享元模式可以极大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能;但也在一定程度上提高了系统的复杂性,需要分离出外部状态和内部状态,而且内部状态具有固化特征,不应该随外部状态改变而改变。
参考:http://www.cnblogs.com/chenssy/p/3330555.html
http://www.cnblogs.com/java-my-life/archive/2012/04/26/2468499.html