flyweight享元模式是实现对象的共享,减少重复数据的存储,从而减少内存分配的开销。享元模式融合了工厂模式和单例模式的思想,实际上也可以说享元模式是特殊的工厂模式。
如果要创建同个对象的n个实例,而通常这n个实例中的m个属性的值大部分或全部是相同的,那么最坏的情况就会有n*m个相同的数据占据了不同的内存空间,如果n*m的值较大的话,就可以考虑flyweight享元模式了。享元模式就把这m个相同的属性提取出来,结合单例模式和工厂模式,来实现相同属性值的实例分配到同一块内存空间(这样就只占用了1*m个内存空间了)。这m个属性通常叫内在信息,而其他会动态变化的信息叫外部信息。
享元模式的基本架构:
public interface FlyweightIntr {//接口
public String get();
}
public class FlyweightFactory {//享元工厂
private HashMap lstFlyweight;
private static FlyweightFactory factory = new FlyweightFactory();
private FlyweightFactory() {
lstFlyweight = new HashMap();
}
public synchronized FlyweightIntr getFlyweight(String str) {//根据str获取FlyweightIntr实例
if (lstFlyweight.get(str) == null) {//如果不存在,则新建
FlyweightIntr fw = new Flyweight(str);
lstFlyweight.put(str, fw);
return fw;
} else {//如果已经记录了,则获取
return (FlyweightIntr) lstFlyweight.get(str);
}
}
public static FlyweightFactory getInstance() {//享元工厂
return factory;
}
private class Flyweight implements FlyweightIntr {
private String str;
private Flyweight(String str) {
this.str = str;
}
private void set(String str) {
this.str = str;
}
public String get() {
return str;
}
}
public class MyClass {
String myStr;
FlyweightIntr obj;
public MyClass(String myStr, FlyweightIntr fw) {
this.myStr = myStr;
obj = fw;
}
public void print() {
System.out.println(myStr+" "+obj.get());
}
}
public class Main{
public static void main(String args[]){
FlyweightFactory factory = FlyweightFactory.getInstance();
FlyweightIntr flyweight = factory.getFlyweight("1");
MyClass myClass = new MyClass("a",flyweight);
myClass.print();
flyweight = factory.getFlyweight("1");
myClass = new MyClass("b",flyweight);
myClass.print();
flyweight = factory.getFlyweight("2");
myClass = new MyClass("c",flyweight);
myClass.print();
flyweight = factory.getFlyweight("2");
myClass = new MyClass("d",flyweight);
myClass.print();
}
}
利用享元模式的思想,进一步的演化,可以把一些不变的数据,放在外部文件作为模版,以便复用。