当一个应用中使用了大量的对象,会造成内存开销大,对象的大部分状态和参数(内部状态)都是相同的时候,可以使用享元模式。使用享元模式可以使这些对象都共享相同的实例。降低存储开销,而对象之间的不同的状态参数(外部状态)则使用外部参数传入来实现。
单纯的享元模式涉及到的角色主要有三个。
抽象享元角色:给出一个抽象接口,以规定具体享元角色需要实现的方法。
具体享元角色:实现抽象享元角色的接口,如果有内蕴状态(具体变量)的话,必须负责为内蕴状态提供存储空间(对其进行保存或者将值赋给新生成一个变量)。
享元工厂:负责创建和管理享元角色。此工厂需保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
可以发现享元模式是简单工厂模式的包装,只是使用场景不一样。
java总的String类型的变量就是享元模式的实现。
具体实现代码如下:
新建一个抽象享元角色抽象接口:
package flyWeight;
public interface FlyWeight {
public void operate(String s);
}
再建一个具体享元角色:
package flyWeight;
public class ConcreteFlyWeight implements FlyWeight {
private String str;// 内蕴状态
public ConcreteFlyWeight(String str) {
this.str = str;
}
@Override
public void operate(String s) {
System.out.println("内蕴变量:" + str);
System.out.println("外蕴变量:" + s);
}
}
再建一个享元工厂:
package flyWeight;
import java.util.Hashtable;
public class FlyWeightFactory {
public FlyWeightFactory() {
}
private Hashtable<String, ConcreteFlyWeight> flyWeights = new Hashtable<String, ConcreteFlyWeight>();
public ConcreteFlyWeight factory(String str) {
ConcreteFlyWeight cfw;
cfw = flyWeights.get(str);
if (null == cfw) {
cfw = new ConcreteFlyWeight(str);
flyWeights.put(str, cfw);
}
return cfw;
}
public int getFlyWeightSie() {
return flyWeights.size();
}
测试下:
package flyWeight;
/**
* 享元模式
*
* @author mercy
*
*/
public class Test {
public static void main(String[] args) {
// 创建享元工厂
FlyWeightFactory factory = new FlyWeightFactory();
// 获取享元对象
FlyWeight fw1 = factory.factory("str1");
FlyWeight fw2 = factory.factory("str2");
FlyWeight fw3 = factory.factory("str3");
fw1.operate("str1 fly Weight");
fw2.operate("str2 fly Weight");
fw3.operate("str3 fly Weight");
}
}
测试结果为:
内蕴变量:str1
外蕴变量:str1 fly Weight
内蕴变量:str2
外蕴变量:str2 fly Weight
内蕴变量:str3
外蕴变量:str3 fly Weight