一、定义

使用共享的方式来有效的支持大量细粒度的对象。

说明:享元模式中的Flyweight分为内部状态(intrinsic)和外部状态(extrinsic),内部状态不会随环境的改变而改变,是用来共享的,对于任何一个享元对象它的值都是相同的;外部状态是会随环境的改变而改变的。在FlyweightFactory中维护一个Flyweight pool来存放内部状态的对象。

二、类图表示

享元模式

三、实现

1、Flyweight

package pattern.structual.flyweight;

public abstract class Flyweight {

	protected char symbol;
	
	protected int x;
	protected int y;
	
	public Flyweight(char symbol) {
		this.symbol = symbol;
	}
	
	@Override
	public String toString() {
		return String.format("%s(%s, %s)", this.symbol, this.x, this.y);
	}
	
	public abstract void operation(int extrinsicState);
}


package pattern.structual.flyweight;

public class ConcreteFlyweight extends Flyweight {

	public ConcreteFlyweight(char symbol) {
		super(symbol);
	}

	@Override
	public void operation(int extrinsicState) {
		this.x = extrinsicState;
		this.y = extrinsicState * 2;
		System.out.println("set shareable flyweight extrinsicstate " + this);
	}

}


package pattern.structual.flyweight;

public class UnsharedConcreteFlyweight extends Flyweight {

	public UnsharedConcreteFlyweight(char symbol) {
		super(symbol);
	}

	@Override
	public void operation(int extrinsicState) {
		this.x = extrinsicState + 1;
		this.y = extrinsicState - 1;
		System.out.println("UnsharedConcreteFlyweight: " + this);
	}

}

2、FlyweightFactory

package pattern.structual.flyweight;

import java.util.Hashtable;

public class FlyweightFactory {

	private Hashtable<Character, Flyweight> flyweights = new Hashtable<>();
	
	public Flyweight getFlyweight(char key){
		Flyweight flyweight = flyweights.get(key);
		if(flyweight == null){
			switch(key){
				case 'A':
					flyweight = new ConcreteFlyweight('A');
					break;
				case 'B':
					flyweight = new ConcreteFlyweight('B');
					break;
				default:
					flyweight = new ConcreteFlyweight('C');
					break;
			}
			flyweights.put(key, flyweight);
			System.out.println(String.format("created shareable flyweight: %s", key));
		}else{
			System.out.println(String.format("get %s from shared flyweight", key));
		}
		return flyweight;
	}
}

四、使用

package pattern.structual.flyweight;

public class Client {

	public static void main(String[] args) {
		int extrinsicState = 10;
		FlyweightFactory factory = new FlyweightFactory();
		
		char[] chars = new char[]{'A','B','A','A','C','A','B'};
		Flyweight sharedFw = null;
		for(char c : chars){
			sharedFw = factory.getFlyweight(c);
			sharedFw.operation(--extrinsicState);
			System.out.println();
		}
		
		UnsharedConcreteFlyweight unSharedFw = new UnsharedConcreteFlyweight('X');
		unSharedFw.operation(extrinsicState);
		
	}
}

  • 程序输出:

享元模式测试程序输出

五、适用场合

  • 当系统中某个类型的对象实例较多时
  • 由于使用了大量对象,造成了很大的存储开销