定义:
享元模式是池技术的重要实现方式,降低大量重复的、细粒度的类在内存中的开销
使用共享对象可以有效地支持大量的细粒度的对象。
享元模式是以共享的方式高效的支持大量的细粒度对象,享元对象能做到共享的关键是区分内部状态和外部状态
- 内部状态是存储享元对象内部的、可以共享的信息,而且不会随环境变化而改变
- 外部状态是随环境改变而改变且不可以共享的状态,享元对象的外部状态必须由客户端保存,并在享元对象被创建后,需要使用时再i传入享元对象内部。
角色:
- 抽象享元角色:该角色对享元类进行抽象,需要外部状态的操作可以通过参数的形式将外部状态传入
- 具体享元:该角色实现抽象享元定义的义务,注意享元对象的内部必须与环境有关,而且使得享元对象可以在系统内共享
- 享元工厂:该角色构造一个容器池,负责创建和管理享元角色,并提供从池容器中获得对象的方法,保证享元对象可以被系统适当的共享,当一个客户端对象请求一个享元对象时,享元工厂会检查系统是否已经有一个符合要求的对象,如果已经有了,则会返回这个,否则新建。
- 客户端角色:该角色需要自行存储所有享元对象的外部状态
优点:
- 大幅减少内存中对象的数量,降低程序内存的占用,提高性能,但是相应付出的代价也很大
- 享元模式增加了系统的复杂性,需要分出外部状态和内部状态,而且内部状态有固话特性,不应该随外部状态改变而改变,使得逻辑复杂化
- 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间变长
场景:
- 系统中有大量的相似对象,而且对象耗费大量内存
- 细粒度对象都具备较接近的外部状态,而且内部状态与环境无关,即对象没有特定的身份
- 需要缓存池的场景
Java中的String Interger Boolean Character等类都通过享元模式提供了内部的池化机制
实例:对象池
用内部状态存放对象到hashmap中,调用operator输出外部状态
package 享元模式;
public interface Flyweight {
public abstract void operation(String extrinsicState);
}
package 享元模式;
public class ConcreteFlyweight implements Flyweight{
private String intrinsicState; //内部状态
public ConcreteFlyweight(String intrString){
this.intrinsicState = intrString;
}
public void operation(String extrinsicState) {
// TODO 自动生成的方法存根
System.out.println("内部状态"+intrinsicState+"\n外补状态"+extrinsicState);
}
}
package 享元模式;
import java.util.HashMap;
import java.util.Map;
public class FlyweightFactory {
private static Map<String, Flyweight> pool = new HashMap<String, Flyweight>();
private FlyweightFactory() {
}
public static Flyweight getFlyweight(String intrinsicState) {
Flyweight fliFlyweight = pool.get(intrinsicState);
if(fliFlyweight == null ){
fliFlyweight = new ConcreteFlyweight(intrinsicState);
pool.put(intrinsicState, fliFlyweight);
}else{
System.out.println("已有对象");
}
return fliFlyweight;
}
}
package 享元模式;
public class Main {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Flyweight flyweight = FlyweightFactory.getFlyweight("强月城准备");
flyweight.operation("强月城准备完成");
Flyweight flyweight1 = FlyweightFactory.getFlyweight("qyc准备");
flyweight1.operation("qyc准备完成");
Flyweight flyweight2 = FlyweightFactory.getFlyweight("强月城准备");
flyweight2.operation("强月城第二次准备完成");
}
}
内部状态强月城准备
外补状态强月城准备完成
内部状态qyc准备
外补状态qyc准备完成
已有对象
内部状态强月城准备
外补状态强月城第二次准备完成