简介
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
- Flyweight: 抽象享元类。所有具体享元类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部专题
- ConcreteFlyweight: 具体享元类。指定内部状态,为内部状态增加存储空间。
- FlyweightFactory: 享元工厂类。用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)
- 内部状态是存储在享元对象内部,一般在构造时确定或通过setter设置,并且不会随环境改变而改变的状态,因此内部状态可以共享。
- 外部状态是随环境改变而改变、不可以共享的状态。外部状态在需要使用时通过客户端传入享元对象。外部状态必须由客户端保存。
类图
代码
/**
* 抽象享元类
* @author: 张彬
* @date: 2018年5月30日 上午11:11:39
* @version: V1.0
* @review: 张彬/2018年5月30日 上午11:11:39
*/
public interface FlyWeight {
public void operation(String externalState);
}
/**
* 具体享元类
* @author: 张彬
* @date: 2018年5月30日 上午11:12:45
* @version: V1.0
* @review: 张彬/2018年5月30日 上午11:12:45
*/
public class ConcreteFlyWeight implements FlyWeight {
private String name;
public ConcreteFlyWeight(String name) {
this.name = name;
}
@Override
public void operation(String externalState) {
System.out.println(String.format("name = {%s}, outerState = {%s}", this.name, externalState));
}
}
/**
* 享元工厂
* @author: 张彬
* @date: 2018年5月30日 上午11:15:26
* @version: V1.0
* @review: 张彬/2018年5月30日 上午11:15:26
*/
public class FlyWeightFactory {
private static ConcurrentHashMap<String, FlyWeight> allFlyWeight = new ConcurrentHashMap<String, FlyWeight>();
public static FlyWeight getFlyWeight(String name) {
if (allFlyWeight.get(name) == null) {
System.out.println(String.format("Instance of name = {%s} does not exist, creating it",name));
FlyWeight flyWeight = new ConcreteFlyWeight(name);
System.out.println(String.format("Instance of name = {%s} created",name));
allFlyWeight.put(name, flyWeight);
}
return allFlyWeight.get(name);
}
}
/**
* 测试
* @author: 张彬
* @date: 2018年5月30日 下午2:13:27
* @version: V1.0
* @review: 张彬/2018年5月30日 下午2:13:27
*/
public class Client {
public static void main(String[] args) {
FlyWeight q1 = FlyWeightFactory.getFlyWeight("oracleQuery");
q1.operation("Statement1");
FlyWeight q2 = FlyWeightFactory.getFlyWeight("oracleQuery");
q2.operation("Statement1");
FlyWeight q3 = FlyWeightFactory.getFlyWeight("oracleQuery");
q3.operation("Statement1");
FlyWeight q4 = FlyWeightFactory.getFlyWeight("oracleQuery");
q4.operation("Statement1");
FlyWeight w1 = FlyWeightFactory.getFlyWeight("oracleWrite");
w1.operation("Statement1");
FlyWeight w2 = FlyWeightFactory.getFlyWeight("oracleWrite");
w2.operation("Statement1");
FlyWeight w3 = FlyWeightFactory.getFlyWeight("oracleWrite");
w3.operation("Statement1");
}
}
输出结果:
Instance of name = {oracleQuery} does not exist, creating it
Instance of name = {oracleQuery} created
name = {oracleQuery}, outerState = {Statement1}
name = {oracleQuery}, outerState = {Statement1}
name = {oracleQuery}, outerState = {Statement1}
name = {oracleQuery}, outerState = {Statement1}
Instance of name = {oracleWrite} does not exist, creating it
Instance of name = {oracleWrite} created
name = {oracleWrite}, outerState = {Statement1}
name = {oracleWrite}, outerState = {Statement1}
name = {oracleWrite}, outerState = {Statement1}
总结
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:外部状态由客户端保存,共享对象读取外部状态的开销可能比较大;享元模式要求将内部状态与外部状态分离,这使得程序的逻辑复杂化,同时也增加了状态维护成本