有时候系统中存在有大量的细粒度的对象,并且这些细粒度的对象有很多存在重复的对象,
还有一种情况是系统中的大量细粒度对象整体上并不重复,但是在每个对象的部分数据上存在重复。
为了避免这种现象我们需要通过缓存包含重复数据的对象,让这些对象只出现一次,从而减少内存的消耗。

因此我们需要对这些细粒度的对象的组成进行分类,分出哪些数据是不变的并且重复出现的,称之为内部变量,哪些数据是经常变化的,我们称之为外部变量,我们需要缓存的是哪些不变且重复的内部变量,而哪些变化的外部变量就不需要缓存了,一般我们会把外部状态分离出来,放到外部让应用在使用的时候进行维护并在需要的时候传递给享元对象使用。
这就是享元模式的基本思想,它的设计重点在于分离变与不变。

public class Flyweight {
private long id;
private String name;
private String sex;
private String classNo;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
public Flyweight(String key){
String[] internalkey = key.split("-");
this.sex = internalkey[0];
this.classNo = internalkey[1];
}
}
public class ConcreFlyweight extends Flyweight {
private String key;
public ConcreFlyweight(String key) {
super(key);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}

public String toString() {
return "Id = "+super.getId() +" Name = "+super.getName()
+" Sex = "+super.getSex() +" Class No."+ super.getClassNo();
}
}
public class FlyweightFactory {

private static class FlyweightFactoryHolder {
public static FlyweightFactory instance = new FlyweightFactory();
}
private FlyweightFactory(){}

public static FlyweightFactory getInstance() {
return FlyweightFactoryHolder.instance;
}

private Map<String,Flyweight> flyweightCache = new HashMap<String,Flyweight>();
public Flyweight getFlyweight(String key) {
Flyweight obj = flyweightCache.get(key);
if(obj == null) {
obj = new ConcreFlyweight(key);
flyweightCache.put(key, obj);
System.out.println("新建一个对象,添加到缓存器");
}else{
System.out.println("直接使用缓存器中现有的");
}
return obj;
}
}
public class Client {
public static void main(String args[]) {
for(int i =0 ; i<2 ;i++) {
for(int j =0;j<10;j++) {
if(i==0) {
FlyweightFactory.getInstance().getFlyweight("Boy-Class"+j);
}else{
FlyweightFactory.getInstance().getFlyweight("Girl-Class"+j);
}
}
}
Flyweight fly = FlyweightFactory.getInstance().getFlyweight("Boy-Class6");
fly.setId(1001);
fly.setName("jimmy");
System.out.println(fly.toString());

Flyweight fly2 = FlyweightFactory.getInstance().getFlyweight("Boy-Class60");
fly2.setId(1003);
fly2.setName("jimmy2");
System.out.println(fly2.toString());
}
}
Contents