形象比喻:
每天给MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight, MM的名字就是提取出来的外部特征。
它通过与其他类似对象共享数据来减小内存占用。也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式。Flyweight的内部状态是用来共享的,Flyweightfactory负责维护一个对象存储池(FlyweightPool)来存放内部状态的对象。为了调用方便,FlyweightFactory类一般使用Singleton模式实现。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度。
优缺点:
1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
2)享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
1.Flyweight
描述一个接口,通过这个接口flyweight可以接受并作用于外部状态。
2.ConcreteFlyweight
实现Flyweight接口,并为内部状态(如果有的话)增加存储空间。
ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的;即,它必须独立于ConcreteFlyweight对象的场景。
3.UnsharedConcreteFlyweight
并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。
在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
4.FlyweightFactory
创建并管理flyweight对象。
确保合理地共享flyweight。当用户请求一个flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
涉及的文件
Flyweight. java -- 接口
FlyweightImpl.java -- 享元实现类
FlyweightFactory.java -- 享元工厂
TestMain.java
/** * @author oscar999 * @date 2013-7-29 * @version V1.0 */ package designptn.flyweight; public interface Flyweight { void action(int arg); }
/** * @author oscar999 * @date 2013-7-29 * @version V1.0 */ package designptn.flyweight; public class FlyweightImpl implements Flyweight { public void action(int arg) { System.out.println("Parameter Value is:" + arg); } }
/** * @author oscar999 * @date 2013-7-29 * @version V1.0 */ package designptn.flyweight; import java.util.HashMap; import java.util.Map; public class FlyweightFactory { private static Map<String, Flyweight> flyweights = new HashMap<String, Flyweight>(); public FlyweightFactory(String arg) { flyweights.put(arg, new FlyweightImpl()); } public static Flyweight getFlyweight(String key) { if (flyweights.get(key) == null) { flyweights.put(key, new FlyweightImpl()); } return flyweights.get(key); } public static int getSize() { return flyweights.size(); } }
/** * @author oscar999 * @date 2014-4-25 * @version V1.0 */ package designptn.flyweight; public class TestMain { public static void main(String[] args) { // TODO Auto-generated method stub Flyweight fly1 = FlyweightFactory.getFlyweight("a"); fly1.action(1); Flyweight fly2 = FlyweightFactory.getFlyweight("a"); System.out.println(fly1 == fly2); Flyweight fly3 = FlyweightFactory.getFlyweight("b"); fly3.action(2); Flyweight fly4 = FlyweightFactory.getFlyweight("c"); fly4.action(3); Flyweight fly5 = FlyweightFactory.getFlyweight("d"); fly5.action(4); System.out.println(FlyweightFactory.getSize()); } }
FlyweightFactory.getFlyweight("a") 调用了两次, 只创建了一个Object, 节省了内存空间。
享元模式看上去和单态模式有点类似。
单态是一个Object,
而享元对应的是多个Object