(26)项目多也别傻做——享元模式

享元模式

运用共享技术有效地支持大量细粒度的对象。(摘抄)

这个模式每天在编码的时候都在用,java中的String就用到了享元模式。

String a = "123";
String b = "123";

这个只要认真学过基础的童鞋应该都知道,这两个String对象是同一个对象,都是指向“123”。在这个里面就是用的享元模式。

对于享元模式,我的理解就是新建相同的对象的时候,而且这两个对象去做相同的,那么应该引用已经创建好的对象,而不是去新建一个相同的去浪费内存。这个时候肯定有人会问要是每个对象里面有自己的标识符号,两个对象并不完全相同怎么办,这时就是后面需要提到的——内部状态和外部状态。

简单的共享对象

import java.util.HashMap;

import org.apache.commons.collections.map.HashedMap;

public abstract class Flyweight
{
	public abstract void Operation(int i);
}

public class ConcreteFlyweight extends Flyweight
{

	@Override
	public void Operation(int i) {
		// TODO Auto-generated method stub
		System.out.println(""+i);
	}
	
}
//享元工厂用来判断是否需要生成新的对象
public class FlyweightFactory
{
	private HashMap<String, Flyweight> flyweights = new HashMap<String, Flyweight>();
	
	public Flyweight getfFlyweight (String x)
	{
		if (!flyweights.containsValue(x))
		{
			flyweights.put(x, new ConcreteFlyweight());
			return flyweights.get(x);
		}
		else 
		{
			return flyweights.get(x);
		}
	}
}

class Client
{
	public static void main()
	{
		FlyweightFactory factory = new FlyweightFactory();
		
		Flyweight flyweight1 = factory.getfFlyweight("x");
		Flyweight flyweight2 = factory.getfFlyweight("x");
	}
}

//有些Flyweight不能被共享那么就写一个继承的类直接调用就可以了

最简单的共享就实现了,此时就是开始说一下内部状态和外部状态,在享元对象内部并且不会随环境改变而改变的共享部分称为内部状态随环境改变而改变,不可以共享的状态称为外部状态

当你在写程序的过程中如果能发现这些实例除了几个参数外基本相同,那么把这些参数放到享元的外部,在方法调用时将它们传递进来,就可以通过享元共享大幅度的减少单个实例的数目。(摘抄)

public class User
{
	private String name;

	public String getName() {
		return name;
	}

	public User(String name) {
		super();
		this.name = name;
	}
	
}

public abstract class Flyweight
{
	public abstract void Operation(int i);
	
	public abstract void whoUse(User user);
}

享元模式应用

如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

文章导航