[设计模式-结构型]享元模式(Flyweight )

概括

名称

Flyweight

结构

[设计模式-结构型]享元模式(Flyweight )_第1张图片

动机

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

适用性

  • 一个应用程序使用了大量的对象。

  • 完全由于使用大量的对象,造成很大的存储开销。

  • 对象的大多数状态都可变为外部状态。

  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

  • 应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。



解析

形象比喻:

每天给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

你可能感兴趣的:([设计模式-结构型]享元模式(Flyweight ))