十一、享元Flyweight(结构型)

享元模式可以帮助你运用共享技术有效的支持大量细粒度的对象。Flyweight是一个共享对象,它可以同时在多个场景中使用,并且在每个场景中flyweight都可以作为一个独立的对象——这点和非共享对象的实例没有区别。例如,在文本编辑器中,所有的字符都会在开始时初始化,并在全局内共享所有字符,而不是每个字符就创建对象。

Flyweight适用于有大量的对象,且这些对象可以分为外部状态和内部状态两个部分,这样就可以将内部状态分离开来,创建独立的共享对象。在使用Flyweight时,一般会使用一个FlyweightFactory来帮助用户创建和查找某个特定对象。


public interface Flyweight {
	public String operation();
	public void setLeft(Flyweight node);
	public void setRight(Flyweight node);
	public Flyweight getLeft();
	public Flyweight getRight();
}
public class ConcreteFlyweight implements Flyweight{
	private Flyweight intrinsicState = null;
	private Flyweight left = null;
	private Flyweight right = null;
	
	public ConcreteFlyweight(String value){
		intrinsicState = FlyweightFactory.getFlyweight(value);
	}
	@Override
	public String operation() {
		StringBuilder ss = new StringBuilder(intrinsicState.operation());
		if(left != null) ss.append(left.operation());
		if(right != null) ss.append(right.operation());
		return ss.toString();
	}
	
	@Override
	public void setLeft(Flyweight node) {
		left = node;
	}
	@Override
	public void setRight(Flyweight node) {
		right = node;
	}
	@Override
	public Flyweight getLeft() {
		return left;
	}
	@Override
	public Flyweight getRight() {
		return right;
	}
}
public class FlyweightFactory {
	private static Map<String, Flyweight> pool = new HashMap<>();
	public static Flyweight getFlyweight(String key){
		if(pool.containsKey(key)){
			return pool.get(key);
		} else {
			Flyweight fw = new internalFlyweight(key);
			pool.put(key, fw);
			return fw;
		}
	}
	private static class internalFlyweight implements Flyweight{
		private String value = null;
		
		public internalFlyweight(String value){
			this.value = value;
		}
		@Override
		public String operation() {
			return value;
		}
		
		@Override
		public void setLeft(Flyweight node) {
			throw new RuntimeException("unsupport!");
		}
		@Override
		public void setRight(Flyweight node) {
			throw new RuntimeException("unsupport!");
		}
		@Override
		public Flyweight getLeft() {
			throw new RuntimeException("unsupport!");
		}
		@Override
		public Flyweight getRight() {
			throw new RuntimeException("unsupport!");
		}
	}
}
public class Client {
	@Test
	public void test(){
		Flyweight root = buildTree(new String[]{"a", "b", "c","a","b","c"});
		System.out.println(root.operation());
	}
	//构建一棵节点树,这棵树按照广度优先,一层一层向下
	public Flyweight buildTree(String strs[]){
		return dfs(strs, 0);
	}
	private Flyweight dfs(String strs[], int index){
		Flyweight root = new ConcreteFlyweight(null);
		if(index < strs.length){
			root = new ConcreteFlyweight(strs[index]);
		}
		if(2*index+1 < strs.length){
			root.setLeft(dfs(strs, 2*index+1));
		}
		if(2*index+2 < strs.length){
			root.setRight(dfs(strs, 2*index+2));
		}
		return root;
	}
}

这里将字符作为Flyweight对象,FlyweightFactory内部包含了一个所有Flyweight对象的pool,当查找Flyweight对象时,如果存在pool中,则不再创建而是直接复用,而不存在时,则需要创建。这样字符的内容作为内部状态被共享,而字符间的关系作为外部状态被额外存储在节点信息中。通过Flyweight模式可以在需要大量字符时减少存储字符所需要的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值