享元模式具体事例(元素化合物)带你参透享元模式的原理与作用

相同元素的化合物都是由几种不同的元素组成的,只是含有元素的个数不同,以下是我设计的几个接口和类,能让具有形同元素的化合物共享相同元素在内存中所占的空间。


===========================享元接口==============================

package com.zqs.flyweight;


/**
 * 享元接口
 * @author Administrator
 *
 */
public interface Flyweight {
/**
* 参数:传递进来外部的数据
* 为了扩展方便(根据具体实现传递),所以此处参数传递选择java可变参数
*/
public void operation(Object... extrinsicObjects);
}

===========================享元接口==============================


===========================享元工厂==============================

package com.zqs.flyweight;


import java.util.HashMap;


/**
 * 享元工厂类,采用单例模式
 * @author zqs
 *
 */
public class FlyweightFactory {
//享元池
private HashMap<String, Flyweight> flyweightPool;
private static FlyweightFactory instance = new FlyweightFactory();


private FlyweightFactory() {
flyweightPool = new HashMap<String, Flyweight>();
}

public static FlyweightFactory getInstance() {
return instance;
}


/**
* 获取享元的方法,享元已经存在就从享元池中拿,不存在就创建一个
* @param key 化合物中的元素字符加起来组成的字符串
* @return
*/
public Flyweight getFlyweight(String key) {
Flyweight flyweight = flyweightPool.get(key);
if(flyweight == null) {
flyweight = new CompoundFlyweight(key);
flyweightPool.put(key, flyweight);
}
return flyweight;
}


/**
* 具体享元类作为工厂类的一个内部类,构造方法私有化
* 只有工厂才能产生享元,用户无法自己构造
* 此处是实现享元的一个具体类,化合物类
* @author zqs
*
*/
class CompoundFlyweight implements Flyweight {
private char[] elements;

private CompoundFlyweight(String key) {
int length = key.length();
elements = new char[length];
for(int i=0; i<length; i++) {
elements[i] = key.charAt(i);
}
}

/**
* 此处具体实现,不同的具体享元对象不同
*/
@Override
public void operation(Object... extrinsicObjects) {
//化合物的名称
String name = (String)extrinsicObjects[0];
//元素的个数
int[] counts = (int[])extrinsicObjects[1];

System.out.println("============================================================");
System.out.println("化合物的名字是:" + name + ",共含有" + counts.length + "种元素");

//每种元素的个数
for(int i=0; i<counts.length; i++) {
System.out.println(elements[i] + "元素的个数是:" + counts[i]);
}

}

}


}

===========================享元工厂==============================


=============具体化合物(关联共享的享元对象)========================

package com.zqs.flyweight;


/**
 * 具体化合物
 * @author Administrator
 *
 */
public class Compound {
//化合物名称
private String name;
//元素种类 化合物中的元素字符加起来组成的字符串
private String key;
//内部共享对象,即享元对象
private Flyweight flyweight;
//每种元素的个数
private int[] counts;

/**
* 不提供无参构造函数
* @param name
* @param key
* @param flyweight
* @param counts
*/
public Compound(String name, String key, Flyweight flyweight, int[] counts) {
super();
this.name = name;
this.key = key;
this.flyweight = flyweight;
this.counts = counts;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public String getKey() {
return key;
}


public void setKey(String key) {
this.key = key;
}


public Flyweight getFlyweight() {
return flyweight;
}


public void setFlyweight(Flyweight flyweight) {
this.flyweight = flyweight;
}


public int[] getCounts() {
return counts;
}


public void setCounts(int[] counts) {
this.counts = counts;
}


}

=============具体化合物(关联共享的享元对象)========================


===========================测试程序==============================

package com.zqs.flyweight;


/**
 * 测试程序
 * @author Administrator
 *
 */
public class Application {


/**
* @param args
*/
public static void main(String[] args) {
FlyweightFactory factory = FlyweightFactory.getInstance();

String hoKey = "ho";
String chKey = "ch";
//水
Flyweight h2oCompoundFlyweight = factory.getFlyweight(hoKey);
Compound h2oCompound = new Compound("水", hoKey, h2oCompoundFlyweight, new int[]{2, 1});
h2oCompound.getFlyweight().operation(h2oCompound.getName(), h2oCompound.getCounts());

//双氧水
Flyweight h2o2CompoundFlyweight = factory.getFlyweight(hoKey);
Compound h2o2Compound = new Compound("双氧水", hoKey, h2o2CompoundFlyweight, new int[]{2, 2});
h2o2Compound.getFlyweight().operation(h2o2Compound.getName(), h2o2Compound.getCounts());

//含有同种元素的化合物共享享元池中的享元(享元池在工厂内部),所有打印的地址为true
System.out.println("水(h2o)与双氧水(h2o2)是否共享享元:" + (h2oCompound.getFlyweight() == h2o2Compound.getFlyweight()));

//甲烷
Flyweight ch4CompoundFlyweight = factory.getFlyweight(chKey);
Compound ch4Compound = new Compound("甲烷", chKey, ch4CompoundFlyweight, new int[]{1, 4});
h2o2Compound.getFlyweight().operation(ch4Compound.getName(), ch4Compound.getCounts());

//含有不同种元素的化合物不共享享元池中的享元(享元池在工厂内部),所有打印的地址为false
System.out.println("水(h2o)与甲烷(ch4)是否共享享元:" + (h2oCompound.getFlyweight() == ch4Compound.getFlyweight()));

}


}

===========================测试程序==============================


===========================测试结果==============================



===========================测试结果==============================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值