当一个应用中使用了大量的对象,会造成内存开销大,对象的大部分状态和参数(内部状态)都是相同的时候,可以使用享元模式。使用享元模式可以使这些对象都共享相同的实例。降低存储开销,而对象之间的不同的状态参数(外部状态)则使用外部参数传入来实现。
单纯的享元模式涉及到的角色主要有三个。
抽象享元角色:给出一个抽象接口,以规定具体享元角色需要实现的方法。
具体享元角色:实现抽象享元角色的接口,如果有内蕴状态(具体变量)的话,必须负责为内蕴状态提供存储空间(对其进行保存或者将值赋给新生成一个变量)。
享元工厂:负责创建和管理享元角色。此工厂需保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
可以发现享元模式是简单工厂模式的包装,只是使用场景不一样。
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