享元模式(flyweight pattern)是指运用共享技术来支持大量细粒度对象的复用,避免大量相似类的开销,从而提高系统资源的利用率
享元模式的结构与实现
享元模式的两种状态
1.内部状态,即不会随着环境的改变而改变的可共享部分
2.外部状态,指随着环境改变而改变的不可共享的部分
享元模式的结构
享元模式的主要结构
1.抽象享元(Flyweight)角色,所有具体享元类的基类,为具体享元规范要实现的公共接口,非享元的外部状态以参数的形式通过方法传入
2.具体享元(Concrete Flyweight)角色,实现抽象享元中规定的接口
3.非享元(Unsharable Flyweght)角色,是不可以共享的外部状态,它以参数的形式注入到具体享元的相关方法中
4.享元工厂(Flyweight Factory)角色,负责创建和管理享元角色,当客户对象请求一个享元对象时,享元工厂检查对象是否存在,如果存在则直接返回给客户,如果不存在则创建一个新的享元对象
享元模式的优缺点
优点
1.相同的对象只需要保存一份,这降低了系统中对象的数量,节省了内存开销,从而降低了系统中细粒度对象给内存带来的压力
缺点
1.为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加系统的复杂性
2.读取享元模式的外部状态会使得运行时间稍微变长
享元模式的实现
创建非享元的外部状态,以参数形式传入到具体享元对象中
/**
* 非享元角色 Uncharable Flyweight
* 是不可以共享的外部状态,它以参数形式注入到享元对象方法中
*/
public class UnsharableFlyWeight {
// 中介公司名称
private String name;
public UnsharableFlyWeight(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
创建抽象享元角色,规定所有具体享元类要实现的接口,非享元的外部状态以参数形式传入
/**
* 抽象享元 为具体享元提供要实现的接口,非享元的外部状态通过参数传入
*/
public abstract class FlyWeight {
// 某中介公司获取用户信息
public abstract void operation(UnsharableFlyWeight unsharable);
}
创建具体享元角色,实现抽象享元的接口
/**
* 具体享元 Concrete FlyWeight
* 实现抽象享元中规定的接口
*/
public class ConcreteFlyWeight extends FlyWeight{
// 用户信息
private String userName;
public ConcreteFlyWeight(String userName){
this.userName = userName;
}
// 某中介公司获取用户信息
@Override
public void operation(UnsharableFlyWeight unsharable) {
System.out.println(unsharable.getName()+",正在获取客户"+userName+"的信息");
}
}
创建享元工厂,负责管理享元对象,当客户端获取享元对象时,如果存在则返回享元对象,如果不存在则创建享元对象
/**
* 享元工厂 FlyWeight Fctory
* 负责创建和管理享元对象,当客户端获取某个享元对象的时候,如果存在则直接返回,如果不存在则创建新的对象
*/
public class FlyWeightFactory {
// 享元工厂管理享元对象
private static Map<String,FlyWeight> flyWeightFactory = new HashMap<String,FlyWeight>();
// 获取享元对象
public static FlyWeight getFlyWeight(String userName){
// 享元对象如果存在则返回
if(flyWeightFactory.containsKey(userName)){
System.out.println("从享元池中获取享元对象");
return flyWeightFactory.get(userName);
}
// 创建享元对象
FlyWeight flyWeight = new ConcreteFlyWeight(userName);
System.out.println("享元池中没有享元对象,开始缓存对象");
// 保存享元对象
flyWeightFactory.put(userName,flyWeight);
return flyWeight;
}
}
测试
public static void main(String[] args) {
// 中介A 获取客户信息
FlyWeight a = FlyWeightFactory.getFlyWeight("A");
a.operation(new UnsharableFlyWeight("中介A"));
// 中介B 获取客户信息
FlyWeight b = FlyWeightFactory.getFlyWeight("A");
b.operation(new UnsharableFlyWeight("中介B"));
// 中介C 获取客户信息
FlyWeight c = FlyWeightFactory.getFlyWeight("A");
c.operation(new UnsharableFlyWeight("中介c"));
// 中介D 获取客户信息
FlyWeight d = FlyWeightFactory.getFlyWeight("B");
c.operation(new UnsharableFlyWeight("中介d"));
}
结果
享元池中没有享元对象,开始缓存对象
中介A,正在获取客户A的信息
从享元池中获取享元对象
中介B,正在获取客户A的信息
从享元池中获取享元对象
中介c,正在获取客户A的信息
享元池中没有享元对象,开始缓存对象
中介d,正在获取客户B的信息
网友评论