所谓享元模式就是运行共享技术有效地支持大量细粒度对象的复用。 系统使用少量对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。
共享模式是支持大量细粒度对象的复用,所以享元模式要求能够共享的对象必须是细粒度对象。
在了解享元模式之前我们先要了解两个概念:内部状态、外部状态。
内部状态:在享元对象内部不随外界环境改变而改变的共享部分。
外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态。
由于享元模式区分了内部状态和外部状态,所以我们可以通过设置不同的外部状态使得相同的对象可以具备一些不同的特性,而内部状态设置为相同部分。在我们的程序设计过程中,我们可能会需要大量的细粒度对象来表示对象,如果这些对象除了几个参数不同外其他部分都相同,这个时候我们就可以利用享元模式来大大减少应用程序当中的对象。如何利用享元模式呢?这里我们只需要将他们少部分的不同的部分当做参数移动到类实例的外部去,然后在方法调用的时候将他们传递过来就可以了。这里也就说明了一点:内部状态存储于享元对象内部,而外部状态则应该由客户端来考虑。
享元模式结构:
享元模式存在如下几个角色:
Flyweight:抽象享元类。所有具体享元类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部专题;
ConcreteFlyweight:具体享元类。指定内部状态,为内部状态增加存储空间。
UnsharedConcreteFlyweight:非共享具体享元类。指出那些不需要共享的Flyweight子类。
FlyweightFactory:享元工厂类。用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)。
享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
public class FlyweightFactory {
// 享元对象池
private HashMap<String, FlyWeight> flyWeights = new HashMap<String, FlyWeight>();
public FlyWeight getFlyWeight(String key) {
// 享元池中存在享元对象,则直接返回
if(flyWeights.containsKey(key)) {
return (FlyWeight) flyWeights.get(key);
} else {
// 享元池中不存在享元对象,并将它放到享元池中
FlyWeight fw = new ConcreteFlyweight();
flyWeights