十、享元模式
享元模式(Flyweight Pattern)顾名思义,就是多个对象共享一个对象,即共用一个内存地址,在实际应用中,采用享元模式的好处就是可以大大节约内存空间,提高系统的运行效率。享元模式经常会出现在工厂模式当中,下面是具体的实现代码:
首先创建一个享元类:
public abstract class Flyweight {
public abstract void operation();
}
/**
* 具体的享元类
* @author Lynn
*
*/
public class ConcreteFlyweight extends Flyweight {
private String str;
public ConcreteFlyweight(String str){
this.str = str;
}
@Override
public void operation() {
System.out.println(str);
}
}
然后创建一个工厂类,用于实体化享元类:
import java.util.Hashtable;
public class FlyweightFactory {
private Hashtable<Object, Flyweight> flyweights = new Hashtable<>();
public Flyweight getFlyweight(Object obj){
Flyweight flyweight = flyweights.get(obj);
if(null == flyweight){
flyweight = new ConcreteFlyweight((String)obj);
flyweights.put(obj, flyweight);
}
return flyweight;
}
public int getFlyweightSize(){
return flyweights.size();
}
}
这里采用hashtable保存每个享元对象,以便下次直接使用,下面是测试方法:
public class Client {
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly1;
Flyweight fly2;
Flyweight fly3;
Flyweight fly4;
Flyweight fly5;
Flyweight fly6;
public Client(){
fly1 = factory.getFlyweight("1");
fly2 = factory.getFlyweight("2");
fly3 = factory.getFlyweight("1");
fly4 = factory.getFlyweight("1");
fly5 = factory.getFlyweight("1");
fly6 = factory.getFlyweight("1");
}
public void showFlyweight(){
fly1.operation();
fly2.operation();
fly3.operation();
fly4.operation();
fly5.operation();
fly6.operation();
int size = factory.getFlyweightSize();
System.out.println("size = " + size);
}
public static void main(String[] args){
Client client = new Client();
client.showFlyweight();
}
}
这样实际上只创建了两个对象,key 为1和key为2的
1
2
1
1
1
1
size = 2
在java中,String就是一个典型的采用享元模式的例子,String是final的,不能被继承的,它也是不可变的,每次创建字符串对象都会保存到对象池中,下次使用到直接从对象池中取出字符串,而不会重新构建对象,下面的例子大家应该不陌生,
String a = "abc";
String b = "abc";
System.out.println(a==b);
“=”是比较的内存地址,这个例子当中打印为true,说明他们的内存地址一样,也就是都指向一个地址,即共享了一个对象。