享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。
也就是说,在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。
比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么久大大节约了资源。
Flyweight类,它是所有具体享元类的父类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
public abstract class Flyweight {
public abstract void operation();
}ConcreteFlyweight是继承Flyweight父类或实现Flyweight接口,并为内部状态增加存储空间。
public class ConcreteFlyweight extends Flyweight {
private String mStr;
public ConcreteFlyweight(String str) {
mStr = str;
}
@Override
public void operation() {
System.out.println("具体享元: " + mStr);
}
}UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。
public class UnsharedConcreteFlyweight extends Flyweight {
private String mStr;
public UnsharedConcreteFlyweight(String str) {
mStr = str;
}
@Override
public void operation() {
System.out.println("不共享的Flyweight: " + mStr);
}
}FlyweightFactory,是一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
public class FlyweightFactory {
private HashMap<String, Flyweight> mFlyweights = new HashMap<String, Flyweight>();
public Flyweight getFlyweight(String key) {
if (!mFlyweights.containsKey(key)) {
mFlyweights.put(key, new ConcreteFlyweight(key));
}
return mFlyweights.get(key);
}
public int getFlyweigtCount() {
int count = mFlyweights.size();
System.out.println("享元个数:" + count);
return count;
}
}调用:
FlyweightFactory factory = new FlyweightFactory();
Flyweight fa = factory.getFlyweight("google");
fa.operation();
Flyweight fb = factory.getFlyweight("google");
fb.operation();
Flyweight fc = factory.getFlyweight("apple");
fc.operation();
Flyweight fd = factory.getFlyweight("google");
fd.operation();
UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight("banana");
uf.operation();
factory.getFlyweigtCount();输出结果:
具体享元: google
具体享元: google
具体享元: apple
具体享元: google
不共享的Flyweight: banana
享元个数:2在享元对象内部并且不会随环境改变而改变的共享部分,可以称为是享元对象的内部状态;
随环境改变而改变的、不可以共享的状态就是外部状态。
享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。
如果能发现这些实例除了几个参数基本上都是相同的,有时就能够大幅度地减少需要实例化的类的数量。
如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;
还有就是对象的大多数状态可以是外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
在Java语音中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在Java中字符串常量都是存在常量池中,Java会确保一个字符串常量在常量池中只有一个拷贝。经典例子如:
String s1 = "hello";
String s2= "hello";
System.out.println("s1和s2是同一个对象吗:" + s1.equals(s2));输出结果是:true。
1344

被折叠的 条评论
为什么被折叠?



